From 24f800c8e28c2bb624b3ed197ef9daa7bc906435 Mon Sep 17 00:00:00 2001 From: Hussain Nagaria Date: Wed, 8 Oct 2025 12:49:47 +0530 Subject: [PATCH] feat: configure background sync frequency --- crm/hooks.py | 39 +++++++++++-------- .../lead_sync_source/lead_sync_source.json | 10 ++++- .../lead_sync_source/lead_sync_source.py | 11 +++++- crm/tasks.py | 32 +++++++++++++++ 4 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 crm/tasks.py diff --git a/crm/hooks.py b/crm/hooks.py index 45f5f955..ca00f15d 100644 --- a/crm/hooks.py +++ b/crm/hooks.py @@ -169,23 +169,28 @@ doc_events = { # Scheduled Tasks # --------------- -# scheduler_events = { -# "all": [ -# "crm.tasks.all" -# ], -# "daily": [ -# "crm.tasks.daily" -# ], -# "hourly": [ -# "crm.tasks.hourly" -# ], -# "weekly": [ -# "crm.tasks.weekly" -# ], -# "monthly": [ -# "crm.tasks.monthly" -# ], -# } +scheduler_events = { + "daily": [ + "crm.tasks.sync_leads_from_sources_daily" + ], + "hourly": [ + "crm.tasks.sync_leads_from_sources_hourly" + ], + "monthly": [ + "crm.tasks.sync_leads_from_sources_monthly" + ], + "cron": { + "*/5 * * * *": [ + "crm.tasks.sync_leads_from_sources_5_minutes" + ], + "*/10 * * * *": [ + "crm.tasks.sync_leads_from_sources_10_minutes" + ], + "*/15 * * * *": [ + "crm.tasks.sync_leads_from_sources_15_minutes" + ], + } +} # Testing # ------- diff --git a/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.json b/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.json index 97fb9206..ce99f1b8 100644 --- a/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.json +++ b/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.json @@ -11,6 +11,7 @@ "column_break_lwcw", "last_synced_at", "enabled", + "background_sync_frequency", "facebook_section", "facebook_page", "column_break_zukm", @@ -69,12 +70,19 @@ { "fieldname": "column_break_zukm", "fieldtype": "Column Break" + }, + { + "default": "Hourly", + "fieldname": "background_sync_frequency", + "fieldtype": "Select", + "label": "Background Sync Frequency", + "options": "Every 5 Minutes\nEvery 10 Minutes\nEvery 15 Minutes\nHourly\nDaily\nMonthly" } ], "grid_page_length": 50, "index_web_pages_for_search": 1, "links": [], - "modified": "2025-10-08 12:09:28.101399", + "modified": "2025-10-08 12:23:22.097933", "modified_by": "Administrator", "module": "Lead Syncing", "name": "Lead Sync Source", diff --git a/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.py b/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.py index 37f89a67..96c862b3 100644 --- a/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.py +++ b/crm/lead_syncing/doctype/lead_sync_source/lead_sync_source.py @@ -17,6 +17,9 @@ class LeadSyncSource(Document): from frappe.types import DF access_token: DF.Password | None + background_sync_frequency: DF.Literal[ + "Every 5 Minutes", "Every 10 Minutes", "Every 15 Minutes", "Hourly", "Daily", "Monthly" + ] enabled: DF.Check facebook_lead_form: DF.Link | None facebook_page: DF.Link | None @@ -34,7 +37,10 @@ class LeadSyncSource(Document): if not self.facebook_lead_form: return - already_active = frappe.db.exists("Lead Sync Source", {"enabled": 1, "facebook_lead_form": self.facebook_lead_form}) + already_active = frappe.db.exists( + "Lead Sync Source", + {"enabled": 1, "facebook_lead_form": self.facebook_lead_form, "name": ["!=", self.name]}, + ) if already_active: frappe.throw(frappe._("A lead sync source is already enabled for this Facebook Lead Form!")) @@ -46,6 +52,9 @@ class LeadSyncSource(Document): @frappe.whitelist() def sync_leads(self): + frappe.enqueue_doc(self.doctype, self.name, "_sync_leads", queue="long") + + def _sync_leads(self): if self.type == "Facebook" and self.access_token: if not self.facebook_lead_form: frappe.throw(frappe._("Please select a lead gen form before syncing!")) diff --git a/crm/tasks.py b/crm/tasks.py new file mode 100644 index 00000000..fcfc0ee1 --- /dev/null +++ b/crm/tasks.py @@ -0,0 +1,32 @@ +import frappe + + +def sync_leads_from_all_enabled_sources(frequency: str | None = None) -> None: + enabled_sources = frappe.get_all( + "Lead Sync Source", filters={"enabled": 1, "background_sync_frequency": frequency}, pluck="name" + ) + for source in enabled_sources: + lead_sync_source = frappe.get_doc("Lead Sync Source", source) + try: + lead_sync_source._sync_leads() + except Exception as _: + frappe.log_error(f"Error syncing leads for source {source}") + + +def sync_leads_from_sources_5_minutes() -> None: + sync_leads_from_all_enabled_sources("Every 5 Minutes") + +def sync_leads_from_sources_10_minutes() -> None: + sync_leads_from_all_enabled_sources("Every 10 Minutes") + +def sync_leads_from_sources_15_minutes() -> None: + sync_leads_from_all_enabled_sources("Every 15 Minutes") + +def sync_leads_from_sources_hourly() -> None: + sync_leads_from_all_enabled_sources("Hourly") + +def sync_leads_from_sources_daily() -> None: + sync_leads_from_all_enabled_sources("Daily") + +def sync_leads_from_sources_monthly() -> None: + sync_leads_from_all_enabled_sources("Monthly") \ No newline at end of file