From b7423f49752fc867eac41ad673842c5aec2cea08 Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Wed, 20 Mar 2024 23:50:52 +0530 Subject: [PATCH 01/15] Soft delete assets from deleted facilities/hospitals --- Makefile | 1 - ...2_alter_asset_current_location_and_more.py | 27 +++++++++++++ .../0423_alter_asset_last_service.py | 24 ++++++++++++ ...4_alter_asset_current_location_and_more.py | 38 +++++++++++++++++++ ...5_alter_asset_current_location_and_more.py | 27 +++++++++++++ ...6_alter_asset_current_location_and_more.py | 38 +++++++++++++++++++ care/facility/models/facility.py | 6 +++ config/celery_app.py | 1 - 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 care/facility/migrations/0422_alter_asset_current_location_and_more.py create mode 100644 care/facility/migrations/0423_alter_asset_last_service.py create mode 100644 care/facility/migrations/0424_alter_asset_current_location_and_more.py create mode 100644 care/facility/migrations/0425_alter_asset_current_location_and_more.py create mode 100644 care/facility/migrations/0426_alter_asset_current_location_and_more.py diff --git a/Makefile b/Makefile index 37bae1c950..3daf36f61d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ DOCKER_VERSION := $(shell docker --version 2>/dev/null) - docker_config_file := 'docker-compose.local.yaml' all: diff --git a/care/facility/migrations/0422_alter_asset_current_location_and_more.py b/care/facility/migrations/0422_alter_asset_current_location_and_more.py new file mode 100644 index 0000000000..4e92b71736 --- /dev/null +++ b/care/facility/migrations/0422_alter_asset_current_location_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.10 on 2024-03-19 13:29 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0421_merge_20240318_1434"), + ] + + operations = [ + migrations.AlterField( + model_name="asset", + name="current_location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.assetlocation" + ), + ), + migrations.AlterField( + model_name="assetlocation", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.facility" + ), + ), + ] diff --git a/care/facility/migrations/0423_alter_asset_last_service.py b/care/facility/migrations/0423_alter_asset_last_service.py new file mode 100644 index 0000000000..03c71521b4 --- /dev/null +++ b/care/facility/migrations/0423_alter_asset_last_service.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.10 on 2024-03-19 17:26 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0422_alter_asset_current_location_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="asset", + name="last_service", + field=models.ForeignKey( + default=None, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="last_service", + to="facility.assetservice", + ), + ), + ] diff --git a/care/facility/migrations/0424_alter_asset_current_location_and_more.py b/care/facility/migrations/0424_alter_asset_current_location_and_more.py new file mode 100644 index 0000000000..1f7c230ead --- /dev/null +++ b/care/facility/migrations/0424_alter_asset_current_location_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.10 on 2024-03-20 11:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0423_alter_asset_last_service"), + ] + + operations = [ + migrations.AlterField( + model_name="asset", + name="current_location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.assetlocation" + ), + ), + migrations.AlterField( + model_name="asset", + name="last_service", + field=models.ForeignKey( + default=None, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="last_service", + to="facility.assetservice", + ), + ), + migrations.AlterField( + model_name="assetlocation", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.facility" + ), + ), + ] diff --git a/care/facility/migrations/0425_alter_asset_current_location_and_more.py b/care/facility/migrations/0425_alter_asset_current_location_and_more.py new file mode 100644 index 0000000000..39b5fb489d --- /dev/null +++ b/care/facility/migrations/0425_alter_asset_current_location_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.10 on 2024-03-20 15:09 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0424_alter_asset_current_location_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="asset", + name="current_location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.assetlocation" + ), + ), + migrations.AlterField( + model_name="assetlocation", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.facility" + ), + ), + ] diff --git a/care/facility/migrations/0426_alter_asset_current_location_and_more.py b/care/facility/migrations/0426_alter_asset_current_location_and_more.py new file mode 100644 index 0000000000..3cb5cea7c7 --- /dev/null +++ b/care/facility/migrations/0426_alter_asset_current_location_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.10 on 2024-03-20 18:10 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0425_alter_asset_current_location_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="asset", + name="current_location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.assetlocation" + ), + ), + migrations.AlterField( + model_name="asset", + name="last_service", + field=models.ForeignKey( + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="last_service", + to="facility.assetservice", + ), + ), + migrations.AlterField( + model_name="assetlocation", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.facility" + ), + ), + ] diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index f417092853..f5557bfb0d 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -174,6 +174,12 @@ class Facility(FacilityBaseModel, FacilityPermissionMixin): class Meta: verbose_name_plural = "Facilities" + def delete(self, *args, **kwargs): + from care.facility.models.asset import Asset, AssetLocation + + Asset.objects.filter(current_location__facility=self).update(deleted=True) + super().delete(self, *args, **kwargs) + def read_cover_image_url(self): if self.cover_image_url: return f"{settings.FACILITY_S3_BUCKET_EXTERNAL_ENDPOINT}/{settings.FACILITY_S3_BUCKET}/{self.cover_image_url}" diff --git a/config/celery_app.py b/config/celery_app.py index d2cd7e2a17..2bf92b6c66 100644 --- a/config/celery_app.py +++ b/config/celery_app.py @@ -12,7 +12,6 @@ # - namespace='CELERY' means all celery-related configuration keys # should have a `CELERY_` prefix. app.config_from_object("django.conf:settings", namespace="CELERY") - app.conf.update(enable_utc=False, timezone="Asia/Kolkata") # Load task modules from all registered Django app configs. app.autodiscover_tasks() From 90251404fbbf5c458ef214359fe44fba63a60380 Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Thu, 21 Mar 2024 07:33:47 +0530 Subject: [PATCH 02/15] soft delete assets on deleting facility-removed redundant migrations --- ...2_alter_asset_current_location_and_more.py | 27 ------------- .../0423_alter_asset_last_service.py | 24 ------------ ...4_alter_asset_current_location_and_more.py | 38 ------------------- ...5_alter_asset_current_location_and_more.py | 27 ------------- ...6_alter_asset_current_location_and_more.py | 38 ------------------- 5 files changed, 154 deletions(-) delete mode 100644 care/facility/migrations/0422_alter_asset_current_location_and_more.py delete mode 100644 care/facility/migrations/0423_alter_asset_last_service.py delete mode 100644 care/facility/migrations/0424_alter_asset_current_location_and_more.py delete mode 100644 care/facility/migrations/0425_alter_asset_current_location_and_more.py delete mode 100644 care/facility/migrations/0426_alter_asset_current_location_and_more.py diff --git a/care/facility/migrations/0422_alter_asset_current_location_and_more.py b/care/facility/migrations/0422_alter_asset_current_location_and_more.py deleted file mode 100644 index 4e92b71736..0000000000 --- a/care/facility/migrations/0422_alter_asset_current_location_and_more.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-19 13:29 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("facility", "0421_merge_20240318_1434"), - ] - - operations = [ - migrations.AlterField( - model_name="asset", - name="current_location", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="facility.assetlocation" - ), - ), - migrations.AlterField( - model_name="assetlocation", - name="facility", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="facility.facility" - ), - ), - ] diff --git a/care/facility/migrations/0423_alter_asset_last_service.py b/care/facility/migrations/0423_alter_asset_last_service.py deleted file mode 100644 index 03c71521b4..0000000000 --- a/care/facility/migrations/0423_alter_asset_last_service.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-19 17:26 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("facility", "0422_alter_asset_current_location_and_more"), - ] - - operations = [ - migrations.AlterField( - model_name="asset", - name="last_service", - field=models.ForeignKey( - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="last_service", - to="facility.assetservice", - ), - ), - ] diff --git a/care/facility/migrations/0424_alter_asset_current_location_and_more.py b/care/facility/migrations/0424_alter_asset_current_location_and_more.py deleted file mode 100644 index 1f7c230ead..0000000000 --- a/care/facility/migrations/0424_alter_asset_current_location_and_more.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-20 11:57 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("facility", "0423_alter_asset_last_service"), - ] - - operations = [ - migrations.AlterField( - model_name="asset", - name="current_location", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, to="facility.assetlocation" - ), - ), - migrations.AlterField( - model_name="asset", - name="last_service", - field=models.ForeignKey( - default=None, - null=True, - on_delete=django.db.models.deletion.PROTECT, - related_name="last_service", - to="facility.assetservice", - ), - ), - migrations.AlterField( - model_name="assetlocation", - name="facility", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, to="facility.facility" - ), - ), - ] diff --git a/care/facility/migrations/0425_alter_asset_current_location_and_more.py b/care/facility/migrations/0425_alter_asset_current_location_and_more.py deleted file mode 100644 index 39b5fb489d..0000000000 --- a/care/facility/migrations/0425_alter_asset_current_location_and_more.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-20 15:09 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("facility", "0424_alter_asset_current_location_and_more"), - ] - - operations = [ - migrations.AlterField( - model_name="asset", - name="current_location", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="facility.assetlocation" - ), - ), - migrations.AlterField( - model_name="assetlocation", - name="facility", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="facility.facility" - ), - ), - ] diff --git a/care/facility/migrations/0426_alter_asset_current_location_and_more.py b/care/facility/migrations/0426_alter_asset_current_location_and_more.py deleted file mode 100644 index 3cb5cea7c7..0000000000 --- a/care/facility/migrations/0426_alter_asset_current_location_and_more.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-20 18:10 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("facility", "0425_alter_asset_current_location_and_more"), - ] - - operations = [ - migrations.AlterField( - model_name="asset", - name="current_location", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, to="facility.assetlocation" - ), - ), - migrations.AlterField( - model_name="asset", - name="last_service", - field=models.ForeignKey( - default=None, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="last_service", - to="facility.assetservice", - ), - ), - migrations.AlterField( - model_name="assetlocation", - name="facility", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, to="facility.facility" - ), - ), - ] From e95842f5921ee36b2e26dfd84e577da3fc8f65b5 Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Sun, 24 Mar 2024 13:20:41 +0530 Subject: [PATCH 03/15] added custom migrations and test cases --- .../0422_soft_delete_existing_assets.py | 21 ++++++++++++++++ .../facility/tests/test_soft_delete_assets.py | 25 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 care/facility/migrations/0422_soft_delete_existing_assets.py create mode 100644 care/facility/tests/test_soft_delete_assets.py diff --git a/care/facility/migrations/0422_soft_delete_existing_assets.py b/care/facility/migrations/0422_soft_delete_existing_assets.py new file mode 100644 index 0000000000..600313d326 --- /dev/null +++ b/care/facility/migrations/0422_soft_delete_existing_assets.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.10 on 2024-03-22 12:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + def soft_delete_facility_assets(self, schema_editor): + facility = self.get_model("facility", "Facility") + asset = self.get_model("facility", "Asset") + facilities = facility.objects.all().values_list("name", flat=True) + asset.objects.exclude(current_location__facility__name__in=facilities).update( + deleted=True + ) + + dependencies = [ + ("facility", "0421_merge_20240318_1434"), + ] + + operations = [ + migrations.RunPython(soft_delete_facility_assets, migrations.RunPython.noop) + ] diff --git a/care/facility/tests/test_soft_delete_assets.py b/care/facility/tests/test_soft_delete_assets.py new file mode 100644 index 0000000000..e1e95a78c0 --- /dev/null +++ b/care/facility/tests/test_soft_delete_assets.py @@ -0,0 +1,25 @@ +from rest_framework import status +from rest_framework.test import APITestCase + +from care.utils.tests.test_utils import TestUtils + + +class SoftDeleteAssets(APITestCase, TestUtils): + @classmethod + def setUpTestData(cls) -> None: + cls.state = cls.create_state() + cls.district = cls.create_district(cls.state) + cls.local_body = cls.create_local_body(cls.district) + cls.super_user = cls.create_super_user("su", cls.district) + cls.facility = cls.create_facility(cls.super_user, cls.district, cls.local_body) + cls.asset_location = cls.create_asset_location(cls.facility) + cls.user = cls.create_user("staff", cls.district, home_facility=cls.facility) + + def setUp(self) -> None: + super().setUp() + self.asset = self.create_asset(self.asset_location) + + def test_asset_soft_delete_api(self): + self.client.delete(f"api/v1/facility/{self.facility.external_id}") + response = self.client.get(f"api/v1/asset?facility={self.facility.external_id}") + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) From ad66e21505ef16fd8627903f895dea71e458710e Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Sun, 24 Mar 2024 16:16:56 +0530 Subject: [PATCH 04/15] Updated soft delete problem --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3daf36f61d..9c8549cf3c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build, re-build, up, down, list, logs, test, makemigrations -DOCKER_VERSION := $(shell docker --version 2>/dev/null) +DOCKER_VERSION := docker --version docker_config_file := 'docker-compose.local.yaml' all: From 1cfed7f34764d8b00b5aaa52485ac676a22da33c Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Sun, 24 Mar 2024 16:32:19 +0530 Subject: [PATCH 05/15] fix back --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9c8549cf3c..3daf36f61d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build, re-build, up, down, list, logs, test, makemigrations -DOCKER_VERSION := docker --version +DOCKER_VERSION := $(shell docker --version 2>/dev/null) docker_config_file := 'docker-compose.local.yaml' all: From 24f3eecf7e4eded3a5915f2f8a98115ede99261b Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Sun, 24 Mar 2024 17:36:42 +0530 Subject: [PATCH 06/15] fix --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 3daf36f61d..c34ae7315b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ .PHONY: build, re-build, up, down, list, logs, test, makemigrations - DOCKER_VERSION := $(shell docker --version 2>/dev/null) docker_config_file := 'docker-compose.local.yaml' From cc8b5c58d156e7284bda1bb36723c3c64bbb6df4 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 25 Mar 2024 20:30:22 +0530 Subject: [PATCH 07/15] Discard changes to Makefile --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index c34ae7315b..37bae1c950 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ .PHONY: build, re-build, up, down, list, logs, test, makemigrations + DOCKER_VERSION := $(shell docker --version 2>/dev/null) + docker_config_file := 'docker-compose.local.yaml' all: From e9afef8bb0d624f72cd5fd28c445f213362f1163 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 25 Mar 2024 20:30:27 +0530 Subject: [PATCH 08/15] Discard changes to config/celery_app.py --- config/celery_app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/config/celery_app.py b/config/celery_app.py index 2bf92b6c66..d2cd7e2a17 100644 --- a/config/celery_app.py +++ b/config/celery_app.py @@ -12,6 +12,7 @@ # - namespace='CELERY' means all celery-related configuration keys # should have a `CELERY_` prefix. app.config_from_object("django.conf:settings", namespace="CELERY") + app.conf.update(enable_utc=False, timezone="Asia/Kolkata") # Load task modules from all registered Django app configs. app.autodiscover_tasks() From 7330609624bb1470240fa0ab0d5c7dd47edc2d9e Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Tue, 26 Mar 2024 01:01:45 +0530 Subject: [PATCH 09/15] added cron job to soft delete --- care/facility/models/facility.py | 6 ------ care/facility/tasks/soft_delete_assets.py | 17 +++++++++++++++++ celerybeat_schedule.py | 8 ++++++++ config/celery_app.py | 3 +++ 4 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 care/facility/tasks/soft_delete_assets.py create mode 100644 celerybeat_schedule.py diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index f5557bfb0d..f417092853 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -174,12 +174,6 @@ class Facility(FacilityBaseModel, FacilityPermissionMixin): class Meta: verbose_name_plural = "Facilities" - def delete(self, *args, **kwargs): - from care.facility.models.asset import Asset, AssetLocation - - Asset.objects.filter(current_location__facility=self).update(deleted=True) - super().delete(self, *args, **kwargs) - def read_cover_image_url(self): if self.cover_image_url: return f"{settings.FACILITY_S3_BUCKET_EXTERNAL_ENDPOINT}/{settings.FACILITY_S3_BUCKET}/{self.cover_image_url}" diff --git a/care/facility/tasks/soft_delete_assets.py b/care/facility/tasks/soft_delete_assets.py new file mode 100644 index 0000000000..2d705c5658 --- /dev/null +++ b/care/facility/tasks/soft_delete_assets.py @@ -0,0 +1,17 @@ +import os + +from celery import Celery + +from care.facility.models.asset import Asset +from care.facility.models.facility import Facility + +broker_url = os.environ.get("CELERY_BROKER_URL") +app = Celery("soft_delete_assets", broker=broker_url) + + +@app.task +def soft_delete_assets_schedule(): + facilities = Facility.objects.all().values_list("name", flat=True) + Asset.objects.exclude(current_location__facility__name__in=facilities).update( + deleted=True + ) diff --git a/celerybeat_schedule.py b/celerybeat_schedule.py new file mode 100644 index 0000000000..03a614cbd3 --- /dev/null +++ b/celerybeat_schedule.py @@ -0,0 +1,8 @@ +from celery.schedules import crontab + +CELERYBEAT_SCHEDULE = { + "soft_delete": { + "task": "care.facility.tasks.soft_delete_assets.soft_delete_assets_schedule", + "schedule": crontab(minute=0, hour=0), + }, +} diff --git a/config/celery_app.py b/config/celery_app.py index d2cd7e2a17..5b87c518b9 100644 --- a/config/celery_app.py +++ b/config/celery_app.py @@ -2,6 +2,8 @@ from celery import Celery +from celerybeat_schedule import CELERYBEAT_SCHEDULE + # set the default Django settings module for the 'celery' program. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") @@ -15,4 +17,5 @@ app.conf.update(enable_utc=False, timezone="Asia/Kolkata") # Load task modules from all registered Django app configs. +app.conf.update(CELERYBEAT_SCHEDULE=CELERYBEAT_SCHEDULE) app.autodiscover_tasks() From 5f01058e0ea546b11e4347cad7f9e4044921a707 Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Wed, 27 Mar 2024 23:48:55 +0530 Subject: [PATCH 10/15] changed soft delete assets --- .../0422_soft_delete_existing_assets.py | 21 ---------------- care/facility/tasks/soft_delete_assets.py | 8 +++--- .../facility/tests/test_soft_delete_assets.py | 25 ------------------- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 care/facility/migrations/0422_soft_delete_existing_assets.py delete mode 100644 care/facility/tests/test_soft_delete_assets.py diff --git a/care/facility/migrations/0422_soft_delete_existing_assets.py b/care/facility/migrations/0422_soft_delete_existing_assets.py deleted file mode 100644 index 600313d326..0000000000 --- a/care/facility/migrations/0422_soft_delete_existing_assets.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-22 12:16 - -from django.db import migrations - - -class Migration(migrations.Migration): - def soft_delete_facility_assets(self, schema_editor): - facility = self.get_model("facility", "Facility") - asset = self.get_model("facility", "Asset") - facilities = facility.objects.all().values_list("name", flat=True) - asset.objects.exclude(current_location__facility__name__in=facilities).update( - deleted=True - ) - - dependencies = [ - ("facility", "0421_merge_20240318_1434"), - ] - - operations = [ - migrations.RunPython(soft_delete_facility_assets, migrations.RunPython.noop) - ] diff --git a/care/facility/tasks/soft_delete_assets.py b/care/facility/tasks/soft_delete_assets.py index 2d705c5658..705cd96a05 100644 --- a/care/facility/tasks/soft_delete_assets.py +++ b/care/facility/tasks/soft_delete_assets.py @@ -11,7 +11,7 @@ @app.task def soft_delete_assets_schedule(): - facilities = Facility.objects.all().values_list("name", flat=True) - Asset.objects.exclude(current_location__facility__name__in=facilities).update( - deleted=True - ) + facilities = Facility.objects.all().values_list("external_id", flat=True) + Asset.objects.exclude( + current_location__facility__external_id__in=facilities + ).update(deleted=True) diff --git a/care/facility/tests/test_soft_delete_assets.py b/care/facility/tests/test_soft_delete_assets.py deleted file mode 100644 index e1e95a78c0..0000000000 --- a/care/facility/tests/test_soft_delete_assets.py +++ /dev/null @@ -1,25 +0,0 @@ -from rest_framework import status -from rest_framework.test import APITestCase - -from care.utils.tests.test_utils import TestUtils - - -class SoftDeleteAssets(APITestCase, TestUtils): - @classmethod - def setUpTestData(cls) -> None: - cls.state = cls.create_state() - cls.district = cls.create_district(cls.state) - cls.local_body = cls.create_local_body(cls.district) - cls.super_user = cls.create_super_user("su", cls.district) - cls.facility = cls.create_facility(cls.super_user, cls.district, cls.local_body) - cls.asset_location = cls.create_asset_location(cls.facility) - cls.user = cls.create_user("staff", cls.district, home_facility=cls.facility) - - def setUp(self) -> None: - super().setUp() - self.asset = self.create_asset(self.asset_location) - - def test_asset_soft_delete_api(self): - self.client.delete(f"api/v1/facility/{self.facility.external_id}") - response = self.client.get(f"api/v1/asset?facility={self.facility.external_id}") - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) From 19415d040e3d77d491054f21816ede9b863ba523 Mon Sep 17 00:00:00 2001 From: Hritesh Shanty Date: Sat, 30 Mar 2024 18:45:47 +0530 Subject: [PATCH 11/15] Changed --- care/facility/tasks/__init__.py | 6 ++++++ care/facility/tasks/soft_delete_assets.py | 17 ++++++----------- celerybeat_schedule.py | 8 -------- config/celery_app.py | 2 -- 4 files changed, 12 insertions(+), 21 deletions(-) delete mode 100644 celerybeat_schedule.py diff --git a/care/facility/tasks/__init__.py b/care/facility/tasks/__init__.py index 6dd696c06e..6ee46a2a02 100644 --- a/care/facility/tasks/__init__.py +++ b/care/facility/tasks/__init__.py @@ -7,6 +7,7 @@ from care.facility.tasks.location_monitor import check_location_status from care.facility.tasks.plausible_stats import capture_goals from care.facility.tasks.redis_index import load_redis_index +from care.facility.tasks.soft_delete_assets import soft_delete_assets_schedule from care.facility.tasks.summarisation import ( summarise_district_patient, summarise_facility_capacity, @@ -74,3 +75,8 @@ def setup_periodic_tasks(sender, **kwargs): check_location_status.s(), name="check_location_status", ) + sender.add_periodic_task( + crontab(hour="23", minute="59"), + soft_delete_assets_schedule.s(), + name="soft_delete_assets", + ) diff --git a/care/facility/tasks/soft_delete_assets.py b/care/facility/tasks/soft_delete_assets.py index 705cd96a05..3e09544ff9 100644 --- a/care/facility/tasks/soft_delete_assets.py +++ b/care/facility/tasks/soft_delete_assets.py @@ -1,17 +1,12 @@ -import os - -from celery import Celery +from celery import shared_task from care.facility.models.asset import Asset from care.facility.models.facility import Facility -broker_url = os.environ.get("CELERY_BROKER_URL") -app = Celery("soft_delete_assets", broker=broker_url) - -@app.task +@shared_task def soft_delete_assets_schedule(): - facilities = Facility.objects.all().values_list("external_id", flat=True) - Asset.objects.exclude( - current_location__facility__external_id__in=facilities - ).update(deleted=True) + facilities = Facility.objects.all().values_list("id", flat=True) + Asset.objects.exclude(current_location__facility__id__in=facilities).update( + deleted=True + ) diff --git a/celerybeat_schedule.py b/celerybeat_schedule.py deleted file mode 100644 index 03a614cbd3..0000000000 --- a/celerybeat_schedule.py +++ /dev/null @@ -1,8 +0,0 @@ -from celery.schedules import crontab - -CELERYBEAT_SCHEDULE = { - "soft_delete": { - "task": "care.facility.tasks.soft_delete_assets.soft_delete_assets_schedule", - "schedule": crontab(minute=0, hour=0), - }, -} diff --git a/config/celery_app.py b/config/celery_app.py index 5b87c518b9..2ff42f39b2 100644 --- a/config/celery_app.py +++ b/config/celery_app.py @@ -1,7 +1,6 @@ import os from celery import Celery - from celerybeat_schedule import CELERYBEAT_SCHEDULE # set the default Django settings module for the 'celery' program. @@ -17,5 +16,4 @@ app.conf.update(enable_utc=False, timezone="Asia/Kolkata") # Load task modules from all registered Django app configs. -app.conf.update(CELERYBEAT_SCHEDULE=CELERYBEAT_SCHEDULE) app.autodiscover_tasks() From 5a111108e5fcb07e4465c42728202e9b3336ace6 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 8 Apr 2024 11:50:27 +0530 Subject: [PATCH 12/15] Discard changes to config/celery_app.py --- config/celery_app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/config/celery_app.py b/config/celery_app.py index 2ff42f39b2..d2cd7e2a17 100644 --- a/config/celery_app.py +++ b/config/celery_app.py @@ -1,7 +1,6 @@ import os from celery import Celery -from celerybeat_schedule import CELERYBEAT_SCHEDULE # set the default Django settings module for the 'celery' program. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") From 1ab2e5a582185eb97c5ad70df291f0aac5ec3d75 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Fri, 23 Aug 2024 17:56:43 +0530 Subject: [PATCH 13/15] fix query --- care/facility/tasks/soft_delete_assets.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/care/facility/tasks/soft_delete_assets.py b/care/facility/tasks/soft_delete_assets.py index 3e09544ff9..6f6e4c2749 100644 --- a/care/facility/tasks/soft_delete_assets.py +++ b/care/facility/tasks/soft_delete_assets.py @@ -1,12 +1,15 @@ from celery import shared_task -from care.facility.models.asset import Asset +from care.facility.models.asset import Asset, AssetLocation from care.facility.models.facility import Facility @shared_task def soft_delete_assets_schedule(): - facilities = Facility.objects.all().values_list("id", flat=True) - Asset.objects.exclude(current_location__facility__id__in=facilities).update( - deleted=True - ) + Asset.objects.filter( + current_location__id__in=AssetLocation._base_manager.filter( + facility__id__in=Facility._base_manager.filter(deleted=True).values_list( + "id", flat=True + ) + ).values_list("id", flat=True) + ).update(deleted=True) From 9f311337583aff175c4bc66716e9a0f19278a9c0 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 23 Sep 2024 00:19:17 +0530 Subject: [PATCH 14/15] revert to soft deleting objects in delete method --- care/facility/models/facility.py | 11 +++++++++++ care/facility/tasks/__init__.py | 6 ------ care/facility/tasks/soft_delete_assets.py | 15 --------------- 3 files changed, 11 insertions(+), 21 deletions(-) delete mode 100644 care/facility/tasks/soft_delete_assets.py diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index 209dbc3869..868b065a33 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -290,6 +290,17 @@ def save(self, *args, **kwargs) -> None: facility=self, user=self.created_by, created_by=self.created_by ) + def delete(self, *args): + from care.facility.models.asset import Asset, AssetLocation + + AssetLocation.objects.filter(facility_id=self.id).update(deleted=True) + Asset.objects.filter( + current_location_id__in=AssetLocation._base_manager.filter( # noqa: SLF001 + facility_id=self.id + ).values_list("id", flat=True) + ).update(deleted=True) + return super().delete(*args) + @property def get_features_display(self): if not self.features: diff --git a/care/facility/tasks/__init__.py b/care/facility/tasks/__init__.py index 6ee46a2a02..6dd696c06e 100644 --- a/care/facility/tasks/__init__.py +++ b/care/facility/tasks/__init__.py @@ -7,7 +7,6 @@ from care.facility.tasks.location_monitor import check_location_status from care.facility.tasks.plausible_stats import capture_goals from care.facility.tasks.redis_index import load_redis_index -from care.facility.tasks.soft_delete_assets import soft_delete_assets_schedule from care.facility.tasks.summarisation import ( summarise_district_patient, summarise_facility_capacity, @@ -75,8 +74,3 @@ def setup_periodic_tasks(sender, **kwargs): check_location_status.s(), name="check_location_status", ) - sender.add_periodic_task( - crontab(hour="23", minute="59"), - soft_delete_assets_schedule.s(), - name="soft_delete_assets", - ) diff --git a/care/facility/tasks/soft_delete_assets.py b/care/facility/tasks/soft_delete_assets.py deleted file mode 100644 index 6f6e4c2749..0000000000 --- a/care/facility/tasks/soft_delete_assets.py +++ /dev/null @@ -1,15 +0,0 @@ -from celery import shared_task - -from care.facility.models.asset import Asset, AssetLocation -from care.facility.models.facility import Facility - - -@shared_task -def soft_delete_assets_schedule(): - Asset.objects.filter( - current_location__id__in=AssetLocation._base_manager.filter( - facility__id__in=Facility._base_manager.filter(deleted=True).values_list( - "id", flat=True - ) - ).values_list("id", flat=True) - ).update(deleted=True) From 9a119227638e9e47e540ba5997beb152dd4b9eb9 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 23 Sep 2024 10:24:27 +0530 Subject: [PATCH 15/15] wrap delete in transaction --- care/facility/models/facility.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index 868b065a33..1c96a89b6a 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -2,7 +2,7 @@ from django.contrib.auth import get_user_model from django.contrib.postgres.fields import ArrayField from django.core.validators import MinValueValidator -from django.db import models +from django.db import models, transaction from django.db.models import IntegerChoices from django.db.models.constraints import CheckConstraint, UniqueConstraint from django.utils.translation import gettext_lazy as _ @@ -290,6 +290,7 @@ def save(self, *args, **kwargs) -> None: facility=self, user=self.created_by, created_by=self.created_by ) + @transaction.atomic def delete(self, *args): from care.facility.models.asset import Asset, AssetLocation