Seth commited on
Commit ·
cf0c608
1
Parent(s): 0ac8264
update
Browse files- backend/app/main.py +23 -7
- frontend/src/pages/Contacts.jsx +1 -1
backend/app/main.py
CHANGED
|
@@ -348,8 +348,10 @@ CONTACTS_TO_LEADS_CAMPAIGN_NAME = "Contacts"
|
|
| 348 |
|
| 349 |
def _convert_contact_to_lead_core(db: Session, contact: Contact) -> dict:
|
| 350 |
"""
|
| 351 |
-
Create a CrmLead row from a Contact
|
| 352 |
-
|
|
|
|
|
|
|
| 353 |
"""
|
| 354 |
email = (_contact_value(contact, "email") or "").strip()
|
| 355 |
if not email:
|
|
@@ -365,9 +367,23 @@ def _convert_contact_to_lead_core(db: Session, contact: Contact) -> dict:
|
|
| 365 |
ln = _contact_value(contact, "last_name") or ""
|
| 366 |
co = _contact_value(contact, "company") or ""
|
| 367 |
ti = _contact_value(contact, "title") or ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
raw = {
|
| 369 |
"source": "contacts_convert",
|
| 370 |
-
"
|
|
|
|
| 371 |
}
|
| 372 |
lead = CrmLead(
|
| 373 |
smartlead_lead_id=f"from-contact-{contact.id}",
|
|
@@ -382,12 +398,11 @@ def _convert_contact_to_lead_core(db: Session, contact: Contact) -> dict:
|
|
| 382 |
last_reply_body="Added from Contacts",
|
| 383 |
last_reply_at=datetime.utcnow(),
|
| 384 |
crm_status="new_lead",
|
| 385 |
-
contact_id=
|
| 386 |
raw_webhook=raw,
|
| 387 |
)
|
| 388 |
db.add(lead)
|
| 389 |
db.flush()
|
| 390 |
-
db.delete(contact)
|
| 391 |
return {"ok": True, "lead_id": lead.id}
|
| 392 |
|
| 393 |
|
|
@@ -688,8 +703,9 @@ async def bulk_delete_contacts(body: BulkContactIdsRequest, db: Session = Depend
|
|
| 688 |
@app.post("/api/contacts/bulk-convert-to-leads")
|
| 689 |
async def bulk_convert_contacts_to_leads(body: BulkContactIdsRequest, db: Session = Depends(get_db)):
|
| 690 |
"""
|
| 691 |
-
For each contact: create a CrmLead (campaign «Contacts»)
|
| 692 |
-
|
|
|
|
| 693 |
"""
|
| 694 |
if not body.contact_ids:
|
| 695 |
raise HTTPException(status_code=400, detail="contact_ids required")
|
|
|
|
| 348 |
|
| 349 |
def _convert_contact_to_lead_core(db: Session, contact: Contact) -> dict:
|
| 350 |
"""
|
| 351 |
+
Create a CrmLead row copied from a Contact. The contact row is kept; only deleted manually.
|
| 352 |
+
|
| 353 |
+
Links the lead via ``contact_id`` so CRM stays consistent. Skips if a lead with the same
|
| 354 |
+
email already exists.
|
| 355 |
"""
|
| 356 |
email = (_contact_value(contact, "email") or "").strip()
|
| 357 |
if not email:
|
|
|
|
| 367 |
ln = _contact_value(contact, "last_name") or ""
|
| 368 |
co = _contact_value(contact, "company") or ""
|
| 369 |
ti = _contact_value(contact, "title") or ""
|
| 370 |
+
rd = contact.raw_data if isinstance(contact.raw_data, dict) else {}
|
| 371 |
+
company_snapshot = {
|
| 372 |
+
"Company Name": _safe_str(co or rd.get("Company Name")),
|
| 373 |
+
"Company Name for Emails": _safe_str(rd.get("Company Name for Emails")),
|
| 374 |
+
"Industry": _safe_str(rd.get("Industry")),
|
| 375 |
+
"# Employees": _safe_str(rd.get("# Employees")),
|
| 376 |
+
"Annual Revenue": _safe_str(rd.get("Annual Revenue")),
|
| 377 |
+
"Last Raised At": _safe_str(rd.get("Last Raised At")),
|
| 378 |
+
"Website": _safe_str(rd.get("Website")),
|
| 379 |
+
"City": _safe_str(rd.get("City")),
|
| 380 |
+
"State": _safe_str(rd.get("State")),
|
| 381 |
+
"Country": _safe_str(rd.get("Country")),
|
| 382 |
+
}
|
| 383 |
raw = {
|
| 384 |
"source": "contacts_convert",
|
| 385 |
+
"source_contact_id": contact.id,
|
| 386 |
+
"company_details": company_snapshot,
|
| 387 |
}
|
| 388 |
lead = CrmLead(
|
| 389 |
smartlead_lead_id=f"from-contact-{contact.id}",
|
|
|
|
| 398 |
last_reply_body="Added from Contacts",
|
| 399 |
last_reply_at=datetime.utcnow(),
|
| 400 |
crm_status="new_lead",
|
| 401 |
+
contact_id=contact.id,
|
| 402 |
raw_webhook=raw,
|
| 403 |
)
|
| 404 |
db.add(lead)
|
| 405 |
db.flush()
|
|
|
|
| 406 |
return {"ok": True, "lead_id": lead.id}
|
| 407 |
|
| 408 |
|
|
|
|
| 703 |
@app.post("/api/contacts/bulk-convert-to-leads")
|
| 704 |
async def bulk_convert_contacts_to_leads(body: BulkContactIdsRequest, db: Session = Depends(get_db)):
|
| 705 |
"""
|
| 706 |
+
For each contact: create a CrmLead (campaign «Contacts») copied from the contact.
|
| 707 |
+
Contacts are not removed; they remain until explicitly deleted. Fails per-row if the
|
| 708 |
+
contact has no email or a lead with the same email already exists.
|
| 709 |
"""
|
| 710 |
if not body.contact_ids:
|
| 711 |
raise HTTPException(status_code=400, detail="contact_ids required")
|
frontend/src/pages/Contacts.jsx
CHANGED
|
@@ -343,7 +343,7 @@ export default function Contacts() {
|
|
| 343 |
variant="outline"
|
| 344 |
size="icon"
|
| 345 |
className="h-9 w-9 shrink-0 text-violet-700 border-violet-200 hover:bg-violet-50"
|
| 346 |
-
title="
|
| 347 |
disabled={bulkDisabled}
|
| 348 |
onClick={() => runBulkAction('leads')}
|
| 349 |
>
|
|
|
|
| 343 |
variant="outline"
|
| 344 |
size="icon"
|
| 345 |
className="h-9 w-9 shrink-0 text-violet-700 border-violet-200 hover:bg-violet-50"
|
| 346 |
+
title="Copy to Leads (contacts remain in Contacts)"
|
| 347 |
disabled={bulkDisabled}
|
| 348 |
onClick={() => runBulkAction('leads')}
|
| 349 |
>
|