Skip to content

Commit

Permalink
Merge pull request #26 from shariquerik/contact-linking
Browse files Browse the repository at this point in the history
feat: Contact linking
  • Loading branch information
shariquerik authored Nov 16, 2023
2 parents cae4517 + 1caaa89 commit 6180899
Show file tree
Hide file tree
Showing 27 changed files with 1,456 additions and 568 deletions.
107 changes: 107 additions & 0 deletions crm/api/contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import frappe


def validate(doc, method):
set_primary_email(doc)
set_primary_mobile_no(doc)
doc.set_primary_email()
doc.set_primary("mobile_no")


def set_primary_email(doc):
if not doc.email_ids:
return

if len(doc.email_ids) == 1:
doc.email_ids[0].is_primary = 1


def set_primary_mobile_no(doc):
if not doc.phone_nos:
return

if len(doc.phone_nos) == 1:
doc.phone_nos[0].is_primary_mobile_no = 1


@frappe.whitelist()
def get_linked_deals(contact):
"""Get linked deals for a contact"""

if not frappe.has_permission("Contact", "read", contact):
frappe.throw("Not permitted", frappe.PermissionError)

deal_names = frappe.get_all(
"CRM Contacts",
filters={"contact": contact, "parenttype": "CRM Deal"},
fields=["parent"],
distinct=True,
)

# get deals data
deals = []
for d in deal_names:
deal = frappe.get_cached_doc(
"CRM Deal",
d.parent,
fields=[
"name",
"organization",
"annual_revenue",
"status",
"email",
"mobile_no",
"deal_owner",
"modified",
],
)
deals.append(deal.as_dict())

return deals


@frappe.whitelist()
def create_new(contact, field, value):
"""Create new email or phone for a contact"""
if not frappe.has_permission("Contact", "write", contact):
frappe.throw("Not permitted", frappe.PermissionError)

contact = frappe.get_doc("Contact", contact)

if field == "email":
contact.append("email_ids", {"email_id": value})
elif field in ("mobile_no", "phone"):
contact.append("phone_nos", {"phone": value})
else:
frappe.throw("Invalid field")

contact.save()
return True


@frappe.whitelist()
def set_as_primary(contact, field, value):
"""Set email or phone as primary for a contact"""
if not frappe.has_permission("Contact", "write", contact):
frappe.throw("Not permitted", frappe.PermissionError)

contact = frappe.get_doc("Contact", contact)

if field == "email":
for email in contact.email_ids:
if email.email_id == value:
email.is_primary = 1
else:
email.is_primary = 0
elif field in ("mobile_no", "phone"):
name = "is_primary_mobile_no" if field == "mobile_no" else "is_primary_phone"
for phone in contact.phone_nos:
if phone.phone == value:
phone.set(name, 1)
else:
phone.set(name, 0)
else:
frappe.throw("Invalid field")

contact.save()
return True
33 changes: 29 additions & 4 deletions crm/api/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,37 @@ def get_contacts():
if frappe.session.user == "Guest":
frappe.throw("Authentication failed", exc=frappe.AuthenticationError)

contacts = frappe.qb.get_query(
contacts = frappe.get_all(
"Contact",
fields=['name', 'first_name', 'last_name', 'full_name', 'image', 'email_id', 'mobile_no', 'phone', 'salutation', 'company_name', 'modified'],
fields=[
"name",
"salutation",
"first_name",
"last_name",
"full_name",
"image",
"email_id",
"mobile_no",
"phone",
"company_name",
"modified"
],
order_by="first_name asc",
distinct=True,
).run(as_dict=1)
)

for contact in contacts:
contact["email_ids"] = frappe.get_all(
"Contact Email",
filters={"parenttype": "Contact", "parent": contact.name},
fields=["email_id", "is_primary"],
)

contact["phone_nos"] = frappe.get_all(
"Contact Phone",
filters={"parenttype": "Contact", "parent": contact.name},
fields=["phone", "is_primary_phone", "is_primary_mobile_no"],
)

return contacts

Expand All @@ -39,7 +64,7 @@ def get_organizations():

organizations = frappe.qb.get_query(
"CRM Organization",
fields=['name', 'organization_name', 'organization_logo', 'website'],
fields=['*'],
order_by="name asc",
distinct=True,
).run(as_dict=1)
Expand Down
14 changes: 10 additions & 4 deletions crm/fcrm/doctype/crm_contacts/crm_contacts.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"column_break_uvny",
"gender",
"mobile_no",
"phone"
"phone",
"is_primary"
],
"fields": [
{
Expand Down Expand Up @@ -55,7 +56,6 @@
"fetch_from": "contact.phone",
"fieldname": "phone",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Phone",
"options": "Phone",
"read_only": 1
Expand All @@ -64,16 +64,22 @@
"fetch_from": "contact.gender",
"fieldname": "gender",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Gender",
"options": "Gender",
"read_only": 1
},
{
"default": "0",
"fieldname": "is_primary",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Is Primary"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-08-25 19:19:27.813526",
"modified": "2023-11-12 14:58:18.846919",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Contacts",
Expand Down
11 changes: 7 additions & 4 deletions crm/fcrm/doctype/crm_deal/api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import json

import frappe
from frappe import _
from frappe.desk.form.load import get_docinfo
from crm.fcrm.doctype.crm_lead.api import get_activities as get_lead_activities


@frappe.whitelist()
Expand All @@ -22,4 +18,11 @@ def get_deal(name):
frappe.throw(_("Deal not found"), frappe.DoesNotExistError)
deal = deal.pop()


deal["contacts"] = frappe.get_all(
"CRM Contacts",
filters={"parenttype": "CRM Deal", "parent": deal.name},
fields=["contact", "is_primary"],
)

return deal
11 changes: 9 additions & 2 deletions crm/fcrm/doctype/crm_deal/crm_deal.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"column_break_bqvs",
"contacts_tab",
"email",
"mobile_no"
"mobile_no",
"contacts"
],
"fields": [
{
Expand Down Expand Up @@ -114,11 +115,17 @@
"options": "Qualification\nDemo/Making\nProposal/Quotation\nNegotiation\nReady to Close\nWon\nLost",
"reqd": 1,
"search_index": 1
},
{
"fieldname": "contacts",
"fieldtype": "Table",
"label": "Contacts",
"options": "CRM Contacts"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-11-06 21:53:50.442404",
"modified": "2023-11-09 19:58:15.620483",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Deal",
Expand Down
71 changes: 70 additions & 1 deletion crm/fcrm/doctype/crm_deal/crm_deal.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,50 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

# import frappe
import frappe
from frappe import _
from frappe.model.document import Document


class CRMDeal(Document):
def validate(self):
self.set_primary_contact()
self.set_primary_email_mobile_no()

def set_primary_contact(self, contact=None):
if not self.contacts:
return

if not contact and len(self.contacts) == 1:
self.contacts[0].is_primary = 1
elif contact:
for d in self.contacts:
if d.contact == contact:
d.is_primary = 1
else:
d.is_primary = 0

def set_primary_email_mobile_no(self):
if not self.contacts:
self.email = ""
self.mobile_no = ""
return

if len([contact for contact in self.contacts if contact.is_primary]) > 1:
frappe.throw(_("Only one {0} can be set as primary.").format(frappe.bold("Contact")))

primary_contact_exists = False
for d in self.contacts:
if d.is_primary == 1:
primary_contact_exists = True
self.email = d.email.strip()
self.mobile_no = d.mobile_no.strip()
break

if not primary_contact_exists:
self.email = ""
self.mobile_no = ""

@staticmethod
def sort_options():
return [
Expand All @@ -17,3 +56,33 @@ def sort_options():
{ "label": 'Email', "value": 'email' },
{ "label": 'Mobile no', "value": 'mobile_no' },
]

@frappe.whitelist()
def add_contact(deal, contact):
if not frappe.has_permission("CRM Deal", "write", deal):
frappe.throw(_("Not allowed to add contact to Deal"), frappe.PermissionError)

deal = frappe.get_cached_doc("CRM Deal", deal)
deal.append("contacts", {"contact": contact})
deal.save()
return True

@frappe.whitelist()
def remove_contact(deal, contact):
if not frappe.has_permission("CRM Deal", "write", deal):
frappe.throw(_("Not allowed to remove contact from Deal"), frappe.PermissionError)

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
Loading

0 comments on commit 6180899

Please sign in to comment.