From 76ee40add292990d39a7fe509cec66a16dfeba41 Mon Sep 17 00:00:00 2001 From: Aysha Date: Sun, 12 Apr 2026 13:13:16 +0530 Subject: [PATCH 1/7] fix: Add `suspended_at` field to Site doctype (cherry picked from commit bd208e44ddc64042023bf93227a22ed2344105fa) --- press/press/doctype/site/site.json | 21 +++++++++++++++++++-- press/press/doctype/site/site.py | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/press/press/doctype/site/site.json b/press/press/doctype/site/site.json index 79db030e338..c768bda1708 100644 --- a/press/press/doctype/site/site.json +++ b/press/press/doctype/site/site.json @@ -12,7 +12,6 @@ "status_before_update", "server", "archive_failed", - "creation_failed", "fatal_site_update", "column_break_3", "bench", @@ -21,6 +20,10 @@ "admin_password", "additional_system_user_created", "backup_timeout", + "section_break_aokd", + "creation_failed", + "column_break_tfvn", + "suspended_at", "config_tab", "hide_config", "host_name", @@ -756,6 +759,20 @@ "fieldtype": "Link", "label": "Fatal Site Update", "options": "Site Update" + }, + { + "fieldname": "section_break_aokd", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_tfvn", + "fieldtype": "Column Break" + }, + { + "fieldname": "suspended_at", + "fieldtype": "Datetime", + "label": "Suspended At", + "read_only": 1 } ], "links": [ @@ -840,7 +857,7 @@ "link_fieldname": "site" } ], - "modified": "2026-02-09 16:05:29.084553", + "modified": "2026-04-12 12:56:22.557860", "modified_by": "Administrator", "module": "Press", "name": "Site", diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py index ea86532a646..180892ea717 100644 --- a/press/press/doctype/site/site.py +++ b/press/press/doctype/site/site.py @@ -223,6 +223,7 @@ class Site(Document, TagHelpers): ] status_before_update: DF.Data | None subdomain: DF.Data + suspended_at: DF.Datetime | None tags: DF.Table[ResourceTag] team: DF.Link timezone: DF.Data | None From 55d28d1988ef7103de0131576c9badfb559012f8 Mon Sep 17 00:00:00 2001 From: Aysha Date: Sun, 12 Apr 2026 13:24:03 +0530 Subject: [PATCH 2/7] fix: Add set_suspended_at_for_suspended_sites patch - Patch to populate `suspended_at` field in Site doctype based on 'Suspend Site' activity record's creation (cherry picked from commit f434146639d597db85bd30ed4bdd350e64c463b2) --- press/patches.txt | 1 + .../set_suspended_at_for_suspended_sites.py | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 press/patches/v0_8_0/set_suspended_at_for_suspended_sites.py diff --git a/press/patches.txt b/press/patches.txt index b882cbb3da9..d4d1482869a 100644 --- a/press/patches.txt +++ b/press/patches.txt @@ -160,3 +160,4 @@ press.press.doctype.proxy_server.patches.set_use_as_proxy_for_agent_and_metrics_ press.patches.v0_0_1.cancel_pending_version_upgrades_for_disabled_bench_groups press.partner.doctype.partner_lead.patches.merge_engagement_stage_to_status press.patches.v0_0_1.add_job_status_index_press_job_step +press.patches.v0_8_0.set_suspended_at_for_suspended_sites \ No newline at end of file diff --git a/press/patches/v0_8_0/set_suspended_at_for_suspended_sites.py b/press/patches/v0_8_0/set_suspended_at_for_suspended_sites.py new file mode 100644 index 00000000000..bc9fe1dccce --- /dev/null +++ b/press/patches/v0_8_0/set_suspended_at_for_suspended_sites.py @@ -0,0 +1,23 @@ +import frappe + + +def execute(): + suspended_sites = frappe.get_all("Site", filters={"status": "Suspended"}, pluck="name") + + if not suspended_sites: + return + + site_suspension_activity_records = frappe.get_all( + "Site Activity", + filters={ + "action": "Suspend Site", + "site": ["in", suspended_sites], + }, + fields=["site", "max(creation) as suspended_at"], + group_by="site", + ) + + for row in site_suspension_activity_records: + frappe.db.set_value("Site", row.site, "suspended_at", row.suspended_at, update_modified=False) + + frappe.db.commit() From e6eaca5a29d449e95f6512b07a6b1b3f52cd3b4d Mon Sep 17 00:00:00 2001 From: Aysha Date: Sun, 12 Apr 2026 13:30:31 +0530 Subject: [PATCH 3/7] fix: Set and unset `suspended_at` field on site suspension and activation respectively (cherry picked from commit fe0e73d50d341653dd7f8fc51c63071cd911506d) --- press/press/doctype/site/site.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py index 180892ea717..58edcce6581 100644 --- a/press/press/doctype/site/site.py +++ b/press/press/doctype/site/site.py @@ -2774,6 +2774,7 @@ def activate(self): def suspend(self, reason=None, skip_reload=False): log_site_activity(self.name, "Suspend Site", reason) self.status = "Suspended" + self.suspended_at = frappe.utils.now_datetime() self.update_site_config({"maintenance_mode": 1}) self.update_site_status_on_proxy("suspended", skip_reload=skip_reload) self.deactivate_app_subscriptions() @@ -2813,6 +2814,7 @@ def reactivate_app_subscriptions(self): def unsuspend(self, reason=None): log_site_activity(self.name, "Unsuspend Site", reason) self.status = "Active" + self.suspended_at = None self.update_site_config({"maintenance_mode": 0}) self.update_site_status_on_proxy("activated") self.reactivate_app_subscriptions() From dd9c940cd65bc9a72a8b80c37b14b1f99a0bfa1d Mon Sep 17 00:00:00 2001 From: Aysha Date: Thu, 16 Apr 2026 12:06:29 +0530 Subject: [PATCH 4/7] fix: Update archive_suspended_sites job - Filter based on newly added suspended_at field value - Move out logic for notifying user before archival (cherry picked from commit c8ef82fc1cc1fa1793024590f7fc07b57a3dd671) --- press/press/doctype/site/site.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py index 58edcce6581..9f644423e06 100644 --- a/press/press/doctype/site/site.py +++ b/press/press/doctype/site/site.py @@ -5075,24 +5075,9 @@ def get_suspended_time(site: str): )[0].creation -def archive_suspended_site(site_dict: SiteToArchive): - archive_after_days = ARCHIVE_AFTER_SUSPEND_DAYS - suspended_days = frappe.utils.date_diff(frappe.utils.today(), get_suspended_time(site_dict.name)) - - if frappe.db.get_value("Bench", site_dict.bench, "managed_database_service"): - return - - if suspended_days <= archive_after_days: - if suspended_days == archive_after_days - NOTIFY_BEFORE_ARCHIVAL_DAYS: - notify_site_scheduled_for_archival(site_dict.name) - return - - site = Site("Site", site_dict.name) - site.archive(reason="Archive suspended site") - - def archive_suspended_sites(): - archive_at_once = 5 + archive_at_once = 6 + archive_threshold = frappe.utils.add_to_date(frappe.utils.now(), days=-ARCHIVE_AFTER_SUSPEND_DAYS) sites = frappe.qb.DocType("Site") site_plans = frappe.qb.DocType("Site Plan") @@ -5102,18 +5087,23 @@ def archive_suspended_sites(): .join(site_plans) .on(sites.plan == site_plans.name) .where( - (sites.status == "Suspended") & (sites.trial_end_date.isnull()) & (site_plans.is_trial_plan == 0) + (sites.status == "Suspended") + & (sites.suspended_at.isnotnull()) + & (sites.suspended_at <= archive_threshold) ) .select(sites.name, sites.team, sites.plan, sites.bench, site_plans.offsite_backups) - .orderby(sites.creation, order=frappe.qb.asc) + .orderby(sites.suspended_at, order=frappe.qb.asc) .limit(archive_at_once) .run(as_dict=True) ) for site_dict in sites_to_drop: try: - archive_suspended_site(site_dict) - frappe.db.commit() + if frappe.db.get_value("Bench", site_dict.bench, "managed_database_service"): + return + + site = Site("Site", site_dict.name) + site.archive(reason="Archive suspended site") except (frappe.QueryDeadlockError, frappe.QueryTimeoutError): frappe.db.rollback() except Exception: From d9542cdd1fd5d7b6117be67ec4135440087b8849 Mon Sep 17 00:00:00 2001 From: Aysha Date: Thu, 16 Apr 2026 12:33:49 +0530 Subject: [PATCH 5/7] fix: Update notify_sites_before_archival method - Add it as a separate job - Filter sites based on suspended_at field (cherry picked from commit 0d351d79e3c9ca52e08e9585a409ea1dd177fbf3) --- press/hooks.py | 1 + press/press/doctype/site/site.py | 47 ++++++++++++------- .../emails/notify_before_site_archival.html | 2 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/press/hooks.py b/press/hooks.py index b6a214b3259..e70ce0fc881 100644 --- a/press/hooks.py +++ b/press/hooks.py @@ -242,6 +242,7 @@ "press.saas.doctype.product_trial_request.product_trial_request.expire_long_pending_trial_requests", "press.overrides.cleanup_ansible_tmp_files", "press.press.doctype.site.site.archive_suspended_sites", + "press.press.doctype.site.site.notify_sites_before_archival", "press.press.doctype.site.site.send_warning_mail_regarding_sites_exceeding_disk_usage", "press.press.doctype.add_on_storage_log.add_on_storage_log.send_disk_extention_notification", "press.press.doctype.server_snapshot_recovery.server_snapshot_recovery.expire_backups", diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py index 9f644423e06..3be5e149e82 100644 --- a/press/press/doctype/site/site.py +++ b/press/press/doctype/site/site.py @@ -5057,14 +5057,6 @@ def create_site_status_update_webhook_event(site: str): create_webhook_event("Site Status Update", record, record.team) -class SiteToArchive(frappe._dict): - name: str - plan: str - team: str - bench: str - offsite_backups: DF.Check - - def get_suspended_time(site: str): return frappe.get_all( "Site Activity", @@ -5079,20 +5071,16 @@ def archive_suspended_sites(): archive_at_once = 6 archive_threshold = frappe.utils.add_to_date(frappe.utils.now(), days=-ARCHIVE_AFTER_SUSPEND_DAYS) - sites = frappe.qb.DocType("Site") - site_plans = frappe.qb.DocType("Site Plan") + Site = frappe.qb.DocType("Site") sites_to_drop = ( - frappe.qb.from_(sites) - .join(site_plans) - .on(sites.plan == site_plans.name) + frappe.qb.from_(Site) .where( - (sites.status == "Suspended") - & (sites.suspended_at.isnotnull()) - & (sites.suspended_at <= archive_threshold) + (Site.status == "Suspended") + & (Site.suspended_at.isnotnull()) + & (Site.suspended_at <= archive_threshold) ) - .select(sites.name, sites.team, sites.plan, sites.bench, site_plans.offsite_backups) - .orderby(sites.suspended_at, order=frappe.qb.asc) + .select(Site.name, Site.bench) .limit(archive_at_once) .run(as_dict=True) ) @@ -5111,6 +5099,29 @@ def archive_suspended_sites(): frappe.db.rollback() +def notify_sites_before_archival(): + notify_threshold = frappe.utils.add_to_date( + frappe.utils.now(), days=-(ARCHIVE_AFTER_SUSPEND_DAYS - NOTIFY_BEFORE_ARCHIVAL_DAYS) + ) + archive_threshold = frappe.utils.add_to_date(frappe.utils.now(), days=-ARCHIVE_AFTER_SUSPEND_DAYS) + + Site = frappe.qb.DocType("Site") + sites_to_notify = ( + frappe.qb.from_(Site) + .where( + (Site.status == "Suspended") + & (Site.suspended_at.isnotnull()) + & (Site.suspended_at <= notify_threshold) + & (Site.suspended_at > archive_threshold) + ) + .select(Site.name) + .run(as_dict=True) + ) + + for site_dict in sites_to_notify: + notify_site_scheduled_for_archival(site_dict.name) + + def notify_site_scheduled_for_archival(site_name: str): try: if frappe.db.exists( diff --git a/press/templates/emails/notify_before_site_archival.html b/press/templates/emails/notify_before_site_archival.html index 03471934e40..f0a3ec3eccf 100644 --- a/press/templates/emails/notify_before_site_archival.html +++ b/press/templates/emails/notify_before_site_archival.html @@ -6,7 +6,7 @@

Hi,

-

This is to inform you that your suspended site {{site_name}} will be automatically archived in {{site_archive_notification_days}} days. Once archived, the site will no longer be accessible.

+

This is to inform you that your suspended site {{site_name}} will be automatically archived within {{site_archive_notification_days}} days. Once archived, the site will no longer be accessible.

A backup of your site will be retained for 6 months in case you want to restore.

{{ utils.separator() }} {{ utils.signature() }} From d2763c14a6d6820a3b8bb51510294dee3b50f9df Mon Sep 17 00:00:00 2001 From: Aysha Date: Thu, 16 Apr 2026 14:44:32 +0530 Subject: [PATCH 6/7] test: Add tests for notifying user and archival of suspended sites (cherry picked from commit 9be84a4eda8e9c6f9b97e66ce1bb9f46b72ee7da) --- press/press/doctype/site/site.py | 26 ++++++------- press/press/doctype/site/test_site.py | 56 +++++++++++++++------------ 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py index 3be5e149e82..3855209d8a4 100644 --- a/press/press/doctype/site/site.py +++ b/press/press/doctype/site/site.py @@ -5071,16 +5071,16 @@ def archive_suspended_sites(): archive_at_once = 6 archive_threshold = frappe.utils.add_to_date(frappe.utils.now(), days=-ARCHIVE_AFTER_SUSPEND_DAYS) - Site = frappe.qb.DocType("Site") + SiteTable = frappe.qb.DocType("Site") sites_to_drop = ( - frappe.qb.from_(Site) + frappe.qb.from_(SiteTable) .where( - (Site.status == "Suspended") - & (Site.suspended_at.isnotnull()) - & (Site.suspended_at <= archive_threshold) + (SiteTable.status == "Suspended") + & (SiteTable.suspended_at.isnotnull()) + & (SiteTable.suspended_at <= archive_threshold) ) - .select(Site.name, Site.bench) + .select(SiteTable.name, SiteTable.bench) .limit(archive_at_once) .run(as_dict=True) ) @@ -5105,16 +5105,16 @@ def notify_sites_before_archival(): ) archive_threshold = frappe.utils.add_to_date(frappe.utils.now(), days=-ARCHIVE_AFTER_SUSPEND_DAYS) - Site = frappe.qb.DocType("Site") + SiteTable = frappe.qb.DocType("Site") sites_to_notify = ( - frappe.qb.from_(Site) + frappe.qb.from_(SiteTable) .where( - (Site.status == "Suspended") - & (Site.suspended_at.isnotnull()) - & (Site.suspended_at <= notify_threshold) - & (Site.suspended_at > archive_threshold) + (SiteTable.status == "Suspended") + & (SiteTable.suspended_at.isnotnull()) + & (SiteTable.suspended_at <= notify_threshold) + & (SiteTable.suspended_at > archive_threshold) ) - .select(Site.name) + .select(SiteTable.name) .run(as_dict=True) ) diff --git a/press/press/doctype/site/test_site.py b/press/press/doctype/site/test_site.py index fa66c83a406..e5551e9fce1 100644 --- a/press/press/doctype/site/test_site.py +++ b/press/press/doctype/site/test_site.py @@ -31,16 +31,16 @@ from press.press.doctype.server.server import BaseServer, Server from press.press.doctype.site.site import ( ARCHIVE_AFTER_SUSPEND_DAYS, + NOTIFY_BEFORE_ARCHIVAL_DAYS, Site, archive_suspended_sites, + notify_sites_before_archival, process_rename_site_job_update, suspend_sites_exceeding_disk_usage_for_last_14_days, ) -from press.press.doctype.site_activity.test_site_activity import create_test_site_activity from press.press.doctype.site_plan.test_site_plan import create_test_plan from press.press.doctype.team.test_team import create_test_team from press.press.doctype.telegram_message.telegram_message import TelegramMessage -from press.saas.doctype.saas_settings.test_saas_settings import create_test_saas_settings from press.utils import get_current_team if typing.TYPE_CHECKING: @@ -527,33 +527,41 @@ def test_apps_are_reordered_to_follow_bench_order(self): @patch("press.press.doctype.site.site.frappe.db.commit", new=Mock()) @patch("press.press.doctype.site.site.frappe.db.rollback", new=Mock()) - def test_archive_suspended_sites_archives_only_sites_with_backup_suspended_longer_than_days(self): - offsite_backup_plan = create_test_plan( - "Site", price_usd=5.0, price_inr=375.0, plan_name="Offsite Backup plan", offsite_backups=True + @patch("frappe.sendmail", new=Mock()) + def test_archive_suspended_sites_and_notify_before_archival(self): + site_to_notify_and_archive = create_test_site() + site_to_notify_and_archive.db_set("status", "Suspended") + site_to_notify_and_archive.db_set( + "suspended_at", + frappe.utils.add_days( + frappe.utils.now_datetime(), + -(ARCHIVE_AFTER_SUSPEND_DAYS - NOTIFY_BEFORE_ARCHIVAL_DAYS), + ), ) - site = create_test_site(plan=offsite_backup_plan.name) - site.db_set("status", "Suspended") - site_activity = create_test_site_activity(site.name, "Suspend Site") - site_activity.db_set( - "creation", frappe.utils.add_days(frappe.utils.now_datetime(), -ARCHIVE_AFTER_SUSPEND_DAYS - 1) + + notify_sites_before_archival() + self.assertTrue( + frappe.db.exists( + "Site Activity", + {"site": site_to_notify_and_archive.name, "action": "Archive Notification"}, + ) ) - site2 = create_test_site(plan=offsite_backup_plan.name) - site2.db_set("status", "Suspended") - site2_activity = create_test_site_activity(site2.name, "Suspend Site") - site2_activity.db_set( - "creation", frappe.utils.add_days(frappe.utils.now_datetime(), -ARCHIVE_AFTER_SUSPEND_DAYS + 1) - ) # site2 suspended recently - site3 = create_test_site(plan=offsite_backup_plan.name) # active site should not be archived - create_test_saas_settings(None, [create_test_app(), create_test_app("erpnext", "ERPNext")]) + site_to_notify_and_archive.db_set( + "suspended_at", + frappe.utils.add_days(frappe.utils.now_datetime(), -ARCHIVE_AFTER_SUSPEND_DAYS - 1), + ) + + site_recent = create_test_site() + site_recent.db_set("status", "Suspended") + site_recent.db_set("suspended_at", frappe.utils.add_days(frappe.utils.now_datetime(), -3)) archive_suspended_sites() - site.reload() - site2.reload() - site3.reload() - self.assertEqual(site.status, "Pending") # to be archived - self.assertEqual(site2.status, "Suspended") - self.assertEqual(site3.status, "Active") + + site_to_notify_and_archive.reload() + site_recent.reload() + self.assertEqual(site_to_notify_and_archive.status, "Pending") # site is being archived + self.assertEqual(site_recent.status, "Suspended") # Do not archive recently suspended site def test_site_usage_exceed_tracking(self): team = create_test_team() From 268a3cfb685d2ed68c6ca78ea9fe84526211dbdd Mon Sep 17 00:00:00 2001 From: Aysha Date: Thu, 16 Apr 2026 16:35:10 +0530 Subject: [PATCH 7/7] fix: Handle archival of all suspended sites in one job - Remove press/press/doctype/site/archive.py file which had logic for: - Archiving suspended trial sites - Deleting offsite backups of archived sites, this is already handled (cherry picked from commit 9de30278cb90440af24e03148d32d3ac5126f498) --- press/hooks.py | 3 +- press/press/doctype/site/archive.py | 91 ----------------------------- press/press/doctype/site/site.py | 9 ++- 3 files changed, 7 insertions(+), 96 deletions(-) delete mode 100644 press/press/doctype/site/archive.py diff --git a/press/hooks.py b/press/hooks.py index e70ce0fc881..b448fc731cf 100644 --- a/press/hooks.py +++ b/press/hooks.py @@ -231,6 +231,7 @@ "press.saas.doctype.product_trial_request.product_trial_request.gather_daily_stats", "press.press.doctype.agent_job.agent_job.agent_poll_count_stats_daily", "press.press.doctype.site_backup.site_backup.delete_backups_for_archived_sites_after_retention", + "press.press.doctype.site.site.notify_sites_before_archival", ], "hourly": [ "press.press.doctype.site.backups.cleanup_local", @@ -242,7 +243,6 @@ "press.saas.doctype.product_trial_request.product_trial_request.expire_long_pending_trial_requests", "press.overrides.cleanup_ansible_tmp_files", "press.press.doctype.site.site.archive_suspended_sites", - "press.press.doctype.site.site.notify_sites_before_archival", "press.press.doctype.site.site.send_warning_mail_regarding_sites_exceeding_disk_usage", "press.press.doctype.add_on_storage_log.add_on_storage_log.send_disk_extention_notification", "press.press.doctype.server_snapshot_recovery.server_snapshot_recovery.expire_backups", @@ -280,7 +280,6 @@ "all": [ "press.auth.flush", "press.press.doctype.site.sync.sync_setup_wizard_status", - "press.press.doctype.site.archive.archive_suspended_trial_sites", "press.press.doctype.agent_job.agent_job.flush", ], "cron": { diff --git a/press/press/doctype/site/archive.py b/press/press/doctype/site/archive.py deleted file mode 100644 index c56a1cd8e36..00000000000 --- a/press/press/doctype/site/archive.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) 2024, Frappe and contributors -# For license information, please see license.txt - -from typing import TYPE_CHECKING - -import frappe - -from press.utils import log_error - -if TYPE_CHECKING: - from press.press.doctype.site.site import Site - - -def archive_suspended_trial_sites(): - ARCHIVE_AFTER_DAYS = 21 - ARCHIVE_AT_ONCE = 10 - - filters = [ - ["status", "=", "Suspended"], - ["trial_end_date", "is", "set"], - [ - "trial_end_date", - "<", - frappe.utils.add_to_date(None, days=-(ARCHIVE_AFTER_DAYS + 1)), - ], # Don't look at sites that are unlikely to be archived - ] - - sites = frappe.get_all( - "Site", - filters=filters, - fields=["name", "team", "trial_end_date"], - order_by="creation asc", - ) - - archived_now = 0 - for site in sites: - if archived_now > ARCHIVE_AT_ONCE: - break - try: - suspension_date = frappe.get_all( - "Site Activity", - filters={"site": site.name, "action": "Suspend Site"}, - pluck="creation", - order_by="creation desc", - limit=1, - )[0] - suspended_days = frappe.utils.date_diff(frappe.utils.today(), suspension_date) - - if suspended_days > ARCHIVE_AFTER_DAYS: - site: Site = frappe.get_doc("Site", site.name, for_update=True) - site.archive(reason="Archive suspended trial site") - archived_now = archived_now + 1 - frappe.db.commit() - except Exception: - log_error("Suspended Site Archive Error") - # Without the rollback the transaction will be implicitly committed - # So we selectively commit and rollback - frappe.db.rollback() - - -def delete_offsite_backups_for_archived_sites(): - archived_sites = frappe.db.sql( - """ - SELECT - backup.site, - COUNT(*) as offsite_backups - FROM - `tabSite Backup` backup - LEFT JOIN - `tabSite` site - ON - backup.site = site.name - WHERE - site.status = "Archived" AND - backup.files_availability = "Available" AND - backup.offsite = True - GROUP BY - backup.site - HAVING - offsite_backups > 1 - ORDER BY - offsite_backups DESC - """, - as_dict=True, - ) - for site in archived_sites: - try: - frappe.get_doc("Site", site.site).delete_offsite_backups() - frappe.db.commit() - except Exception: - frappe.db.rollback() diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py index 3855209d8a4..6bf356638c1 100644 --- a/press/press/doctype/site/site.py +++ b/press/press/doctype/site/site.py @@ -5088,14 +5088,15 @@ def archive_suspended_sites(): for site_dict in sites_to_drop: try: if frappe.db.get_value("Bench", site_dict.bench, "managed_database_service"): - return + continue site = Site("Site", site_dict.name) site.archive(reason="Archive suspended site") + frappe.db.commit() except (frappe.QueryDeadlockError, frappe.QueryTimeoutError): frappe.db.rollback() except Exception: - frappe.log_error(title="Suspended Site Archive Error") + frappe.log_error(title="Suspended Site Archival Error") frappe.db.rollback() @@ -5114,11 +5115,13 @@ def notify_sites_before_archival(): & (SiteTable.suspended_at <= notify_threshold) & (SiteTable.suspended_at > archive_threshold) ) - .select(SiteTable.name) + .select(SiteTable.name, SiteTable.bench) .run(as_dict=True) ) for site_dict in sites_to_notify: + if frappe.db.get_value("Bench", site_dict.bench, "managed_database_service"): + continue notify_site_scheduled_for_archival(site_dict.name)