Rohan Bansal | 76825ab | 2020-04-28 16:08:52 +0530 | [diff] [blame] | 1 | import frappe |
Nabin Hait | 29b8715 | 2022-07-22 15:33:23 +0530 | [diff] [blame] | 2 | from frappe.desk.notifications import notify_mentions |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 3 | from frappe.model.document import Document |
Nabin Hait | 925b9d9 | 2022-06-27 21:58:19 +0530 | [diff] [blame] | 4 | from frappe.utils import cstr, now, today |
| 5 | from pypika import functions |
Rohan Bansal | 76825ab | 2020-04-28 16:08:52 +0530 | [diff] [blame] | 6 | |
| 7 | |
| 8 | def update_lead_phone_numbers(contact, method): |
| 9 | if contact.phone_nos: |
| 10 | contact_lead = contact.get_link_for("Lead") |
| 11 | if contact_lead: |
| 12 | phone = mobile_no = contact.phone_nos[0].phone |
| 13 | |
| 14 | if len(contact.phone_nos) > 1: |
| 15 | # get the default phone number |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 16 | primary_phones = [ |
| 17 | phone_doc.phone for phone_doc in contact.phone_nos if phone_doc.is_primary_phone |
| 18 | ] |
Rohan Bansal | 76825ab | 2020-04-28 16:08:52 +0530 | [diff] [blame] | 19 | if primary_phones: |
| 20 | phone = primary_phones[0] |
| 21 | |
| 22 | # get the default mobile number |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 23 | primary_mobile_nos = [ |
| 24 | phone_doc.phone for phone_doc in contact.phone_nos if phone_doc.is_primary_mobile_no |
| 25 | ] |
Rohan Bansal | 76825ab | 2020-04-28 16:08:52 +0530 | [diff] [blame] | 26 | if primary_mobile_nos: |
| 27 | mobile_no = primary_mobile_nos[0] |
| 28 | |
| 29 | lead = frappe.get_doc("Lead", contact_lead) |
Myuddin khatri | fc0e45d | 2020-05-07 15:11:39 +0530 | [diff] [blame] | 30 | lead.db_set("phone", phone) |
| 31 | lead.db_set("mobile_no", mobile_no) |
Anupam | 6eb7793 | 2021-11-19 10:13:05 +0530 | [diff] [blame] | 32 | |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 33 | |
Anupam | 6eb7793 | 2021-11-19 10:13:05 +0530 | [diff] [blame] | 34 | def copy_comments(doctype, docname, doc): |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 35 | comments = frappe.db.get_values( |
| 36 | "Comment", |
| 37 | filters={"reference_doctype": doctype, "reference_name": docname, "comment_type": "Comment"}, |
| 38 | fieldname="*", |
| 39 | ) |
Anupam | 6eb7793 | 2021-11-19 10:13:05 +0530 | [diff] [blame] | 40 | for comment in comments: |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 41 | comment = frappe.get_doc(comment.update({"doctype": "Comment"})) |
Anupam | 6eb7793 | 2021-11-19 10:13:05 +0530 | [diff] [blame] | 42 | comment.name = None |
| 43 | comment.reference_doctype = doc.doctype |
| 44 | comment.reference_name = doc.name |
| 45 | comment.insert() |
| 46 | |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 47 | |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 48 | def link_communications(doctype, docname, doc): |
Anupam | 31ac101 | 2021-12-17 19:21:08 +0530 | [diff] [blame] | 49 | communication_list = get_linked_communication_list(doctype, docname) |
| 50 | |
| 51 | for communication in communication_list: |
| 52 | communication_doc = frappe.get_doc("Communication", communication) |
| 53 | communication_doc.add_link(doc.doctype, doc.name, autosave=True) |
| 54 | |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 55 | |
Anupam | 31ac101 | 2021-12-17 19:21:08 +0530 | [diff] [blame] | 56 | def get_linked_communication_list(doctype, docname): |
Ankush Menat | 494bd9e | 2022-03-28 18:52:46 +0530 | [diff] [blame] | 57 | communications = frappe.get_all( |
| 58 | "Communication", filters={"reference_doctype": doctype, "reference_name": docname}, pluck="name" |
| 59 | ) |
| 60 | communication_links = frappe.get_all( |
| 61 | "Communication Link", |
| 62 | {"link_doctype": doctype, "link_name": docname, "parent": ("not in", communications)}, |
| 63 | pluck="parent", |
| 64 | ) |
Anupam | 5b40d9e | 2021-12-18 20:12:57 +0530 | [diff] [blame] | 65 | |
Anupam | 31ac101 | 2021-12-17 19:21:08 +0530 | [diff] [blame] | 66 | return communications + communication_links |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 67 | |
| 68 | |
| 69 | def link_communications_with_prospect(communication, method): |
| 70 | prospect = get_linked_prospect(communication.reference_doctype, communication.reference_name) |
| 71 | |
| 72 | if prospect: |
| 73 | already_linked = any( |
| 74 | [ |
| 75 | d.name |
| 76 | for d in communication.get("timeline_links") |
| 77 | if d.link_doctype == "Prospect" and d.link_name == prospect |
| 78 | ] |
| 79 | ) |
| 80 | if not already_linked: |
| 81 | row = communication.append("timeline_links") |
| 82 | row.link_doctype = "Prospect" |
| 83 | row.link_name = prospect |
| 84 | row.db_update() |
| 85 | |
| 86 | |
| 87 | def get_linked_prospect(reference_doctype, reference_name): |
| 88 | prospect = None |
| 89 | if reference_doctype == "Lead": |
| 90 | prospect = frappe.db.get_value("Prospect Lead", {"lead": reference_name}, "parent") |
| 91 | |
| 92 | elif reference_doctype == "Opportunity": |
| 93 | opportunity_from, party_name = frappe.db.get_value( |
| 94 | "Opportunity", reference_name, ["opportunity_from", "party_name"] |
| 95 | ) |
| 96 | if opportunity_from == "Lead": |
Akhil Narang | 3effaf2 | 2024-03-27 11:37:26 +0530 | [diff] [blame] | 97 | prospect = frappe.db.get_value("Prospect Opportunity", {"opportunity": reference_name}, "parent") |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 98 | if opportunity_from == "Prospect": |
| 99 | prospect = party_name |
| 100 | |
| 101 | return prospect |
| 102 | |
| 103 | |
| 104 | def link_events_with_prospect(event, method): |
| 105 | if event.event_participants: |
| 106 | ref_doctype = event.event_participants[0].reference_doctype |
| 107 | ref_docname = event.event_participants[0].reference_docname |
| 108 | prospect = get_linked_prospect(ref_doctype, ref_docname) |
| 109 | if prospect: |
| 110 | event.add_participant("Prospect", prospect) |
| 111 | event.save() |
| 112 | |
| 113 | |
| 114 | def link_open_tasks(ref_doctype, ref_docname, doc): |
| 115 | todos = get_open_todos(ref_doctype, ref_docname) |
| 116 | |
| 117 | for todo in todos: |
| 118 | todo_doc = frappe.get_doc("ToDo", todo.name) |
| 119 | todo_doc.reference_type = doc.doctype |
| 120 | todo_doc.reference_name = doc.name |
Ankush Menat | 63b9795 | 2022-11-28 10:58:35 +0530 | [diff] [blame] | 121 | todo_doc.save() |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 122 | |
| 123 | |
| 124 | def link_open_events(ref_doctype, ref_docname, doc): |
| 125 | events = get_open_events(ref_doctype, ref_docname) |
| 126 | for event in events: |
| 127 | event_doc = frappe.get_doc("Event", event.name) |
| 128 | event_doc.add_participant(doc.doctype, doc.name) |
| 129 | event_doc.save() |
| 130 | |
| 131 | |
| 132 | @frappe.whitelist() |
| 133 | def get_open_activities(ref_doctype, ref_docname): |
| 134 | tasks = get_open_todos(ref_doctype, ref_docname) |
| 135 | events = get_open_events(ref_doctype, ref_docname) |
| 136 | |
| 137 | return {"tasks": tasks, "events": events} |
| 138 | |
| 139 | |
| 140 | def get_open_todos(ref_doctype, ref_docname): |
| 141 | return frappe.get_all( |
| 142 | "ToDo", |
| 143 | filters={"reference_type": ref_doctype, "reference_name": ref_docname, "status": "Open"}, |
| 144 | fields=[ |
| 145 | "name", |
| 146 | "description", |
| 147 | "allocated_to", |
| 148 | "date", |
| 149 | ], |
| 150 | ) |
| 151 | |
| 152 | |
| 153 | def get_open_events(ref_doctype, ref_docname): |
| 154 | event = frappe.qb.DocType("Event") |
| 155 | event_link = frappe.qb.DocType("Event Participants") |
| 156 | |
| 157 | query = ( |
| 158 | frappe.qb.from_(event) |
| 159 | .join(event_link) |
| 160 | .on(event_link.parent == event.name) |
| 161 | .select( |
| 162 | event.name, |
| 163 | event.subject, |
| 164 | event.event_category, |
| 165 | event.starts_on, |
| 166 | event.ends_on, |
| 167 | event.description, |
| 168 | ) |
| 169 | .where( |
| 170 | (event_link.reference_doctype == ref_doctype) |
| 171 | & (event_link.reference_docname == ref_docname) |
| 172 | & (event.status == "Open") |
| 173 | ) |
| 174 | ) |
| 175 | data = query.run(as_dict=True) |
| 176 | |
| 177 | return data |
| 178 | |
| 179 | |
Nabin Hait | 925b9d9 | 2022-06-27 21:58:19 +0530 | [diff] [blame] | 180 | def open_leads_opportunities_based_on_todays_event(): |
| 181 | event = frappe.qb.DocType("Event") |
| 182 | event_link = frappe.qb.DocType("Event Participants") |
| 183 | |
| 184 | query = ( |
| 185 | frappe.qb.from_(event) |
| 186 | .join(event_link) |
| 187 | .on(event_link.parent == event.name) |
| 188 | .select(event_link.reference_doctype, event_link.reference_docname) |
| 189 | .where( |
| 190 | (event_link.reference_doctype.isin(["Lead", "Opportunity"])) |
| 191 | & (event.status == "Open") |
| 192 | & (functions.Date(event.starts_on) == today()) |
| 193 | ) |
| 194 | ) |
| 195 | data = query.run(as_dict=True) |
| 196 | |
| 197 | for d in data: |
| 198 | frappe.db.set_value(d.reference_doctype, d.reference_docname, "status", "Open") |
| 199 | |
| 200 | |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 201 | class CRMNote(Document): |
| 202 | @frappe.whitelist() |
| 203 | def add_note(self, note): |
| 204 | self.append("notes", {"note": note, "added_by": frappe.session.user, "added_on": now()}) |
| 205 | self.save() |
Nabin Hait | 29b8715 | 2022-07-22 15:33:23 +0530 | [diff] [blame] | 206 | notify_mentions(self.doctype, self.name, note) |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 207 | |
| 208 | @frappe.whitelist() |
| 209 | def edit_note(self, note, row_id): |
| 210 | for d in self.notes: |
| 211 | if cstr(d.name) == row_id: |
| 212 | d.note = note |
| 213 | d.db_update() |
| 214 | |
| 215 | @frappe.whitelist() |
| 216 | def delete_note(self, row_id): |
| 217 | for d in self.notes: |
| 218 | if cstr(d.name) == row_id: |
| 219 | self.remove(d) |
| 220 | break |
| 221 | self.save() |