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": |
| 97 | prospect = frappe.db.get_value( |
| 98 | "Prospect Opportunity", {"opportunity": reference_name}, "parent" |
| 99 | ) |
| 100 | if opportunity_from == "Prospect": |
| 101 | prospect = party_name |
| 102 | |
| 103 | return prospect |
| 104 | |
| 105 | |
| 106 | def link_events_with_prospect(event, method): |
| 107 | if event.event_participants: |
| 108 | ref_doctype = event.event_participants[0].reference_doctype |
| 109 | ref_docname = event.event_participants[0].reference_docname |
| 110 | prospect = get_linked_prospect(ref_doctype, ref_docname) |
| 111 | if prospect: |
| 112 | event.add_participant("Prospect", prospect) |
| 113 | event.save() |
| 114 | |
| 115 | |
| 116 | def link_open_tasks(ref_doctype, ref_docname, doc): |
| 117 | todos = get_open_todos(ref_doctype, ref_docname) |
| 118 | |
| 119 | for todo in todos: |
| 120 | todo_doc = frappe.get_doc("ToDo", todo.name) |
| 121 | todo_doc.reference_type = doc.doctype |
| 122 | todo_doc.reference_name = doc.name |
| 123 | todo_doc.db_update() |
| 124 | |
| 125 | |
| 126 | def link_open_events(ref_doctype, ref_docname, doc): |
| 127 | events = get_open_events(ref_doctype, ref_docname) |
| 128 | for event in events: |
| 129 | event_doc = frappe.get_doc("Event", event.name) |
| 130 | event_doc.add_participant(doc.doctype, doc.name) |
| 131 | event_doc.save() |
| 132 | |
| 133 | |
| 134 | @frappe.whitelist() |
| 135 | def get_open_activities(ref_doctype, ref_docname): |
| 136 | tasks = get_open_todos(ref_doctype, ref_docname) |
| 137 | events = get_open_events(ref_doctype, ref_docname) |
| 138 | |
| 139 | return {"tasks": tasks, "events": events} |
| 140 | |
| 141 | |
| 142 | def get_open_todos(ref_doctype, ref_docname): |
| 143 | return frappe.get_all( |
| 144 | "ToDo", |
| 145 | filters={"reference_type": ref_doctype, "reference_name": ref_docname, "status": "Open"}, |
| 146 | fields=[ |
| 147 | "name", |
| 148 | "description", |
| 149 | "allocated_to", |
| 150 | "date", |
| 151 | ], |
| 152 | ) |
| 153 | |
| 154 | |
| 155 | def get_open_events(ref_doctype, ref_docname): |
| 156 | event = frappe.qb.DocType("Event") |
| 157 | event_link = frappe.qb.DocType("Event Participants") |
| 158 | |
| 159 | query = ( |
| 160 | frappe.qb.from_(event) |
| 161 | .join(event_link) |
| 162 | .on(event_link.parent == event.name) |
| 163 | .select( |
| 164 | event.name, |
| 165 | event.subject, |
| 166 | event.event_category, |
| 167 | event.starts_on, |
| 168 | event.ends_on, |
| 169 | event.description, |
| 170 | ) |
| 171 | .where( |
| 172 | (event_link.reference_doctype == ref_doctype) |
| 173 | & (event_link.reference_docname == ref_docname) |
| 174 | & (event.status == "Open") |
| 175 | ) |
| 176 | ) |
| 177 | data = query.run(as_dict=True) |
| 178 | |
| 179 | return data |
| 180 | |
| 181 | |
Nabin Hait | 925b9d9 | 2022-06-27 21:58:19 +0530 | [diff] [blame] | 182 | def open_leads_opportunities_based_on_todays_event(): |
| 183 | event = frappe.qb.DocType("Event") |
| 184 | event_link = frappe.qb.DocType("Event Participants") |
| 185 | |
| 186 | query = ( |
| 187 | frappe.qb.from_(event) |
| 188 | .join(event_link) |
| 189 | .on(event_link.parent == event.name) |
| 190 | .select(event_link.reference_doctype, event_link.reference_docname) |
| 191 | .where( |
| 192 | (event_link.reference_doctype.isin(["Lead", "Opportunity"])) |
| 193 | & (event.status == "Open") |
| 194 | & (functions.Date(event.starts_on) == today()) |
| 195 | ) |
| 196 | ) |
| 197 | data = query.run(as_dict=True) |
| 198 | |
| 199 | for d in data: |
| 200 | frappe.db.set_value(d.reference_doctype, d.reference_docname, "status", "Open") |
| 201 | |
| 202 | |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 203 | class CRMNote(Document): |
| 204 | @frappe.whitelist() |
| 205 | def add_note(self, note): |
| 206 | self.append("notes", {"note": note, "added_by": frappe.session.user, "added_on": now()}) |
| 207 | self.save() |
Nabin Hait | 29b8715 | 2022-07-22 15:33:23 +0530 | [diff] [blame] | 208 | notify_mentions(self.doctype, self.name, note) |
Nabin Hait | f904ac5 | 2022-06-10 11:15:22 +0530 | [diff] [blame] | 209 | |
| 210 | @frappe.whitelist() |
| 211 | def edit_note(self, note, row_id): |
| 212 | for d in self.notes: |
| 213 | if cstr(d.name) == row_id: |
| 214 | d.note = note |
| 215 | d.db_update() |
| 216 | |
| 217 | @frappe.whitelist() |
| 218 | def delete_note(self, row_id): |
| 219 | for d in self.notes: |
| 220 | if cstr(d.name) == row_id: |
| 221 | self.remove(d) |
| 222 | break |
| 223 | self.save() |