From 9dc7e9ff4d800b7b33ac45fbc2ab32963da707af Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 14:19:45 +0530 Subject: [PATCH 01/24] remove django extra fields --- config/settings/base.py | 1 - pyproject.toml | 1 - requirements/base.txt | 1 - 3 files changed, 3 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 984f66aff6..97ad6c0f91 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -84,7 +84,6 @@ "rest_framework", "rest_framework.authtoken", "drf_yasg", - "drf_extra_fields", "django_filters", "simple_history", "ratelimit", diff --git a/pyproject.toml b/pyproject.toml index fbcff50983..83af05e76a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,6 @@ known_third_party = [ "django_rest_passwordreset", "djangoql", "djqscsv", - "drf_extra_fields", "drf_yasg", "dry_rest_permissions", "environ", diff --git a/requirements/base.txt b/requirements/base.txt index b74cc4ef75..488573e3fa 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -18,7 +18,6 @@ djangorestframework==3.11.0 # https://github.com/encode/django-rest-framework djangorestframework-simplejwt==4.5.0 # https://github.com/SimpleJWT/django-rest-framework-simplejwt drf-yasg==1.17.1 # For Api Docs django-filter==2.4.0 -django-extra-fields==2.0.3 # https://github.com/Hipo/drf-extra-fields django-location-field==2.1.0 # https://django-location-field.readthedocs.io/en/latest/ drf-nested-routers==0.91 django-multiselectfield==0.1.12 # https://github.com/goinnn/django-multiselectfield From 6c1a465fe3660a4abe3d6b4425f10c19df66077c Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 14:19:45 +0530 Subject: [PATCH 02/24] remove django location field --- pyproject.toml | 1 - requirements/base.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 83af05e76a..ba1fa783f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,6 @@ known_third_party = [ "healthy_django", "jsonschema", "jwt", - "location_field", "multiselectfield", "partial_index", "phonenumber_field", diff --git a/requirements/base.txt b/requirements/base.txt index 488573e3fa..321927c06e 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -18,7 +18,6 @@ djangorestframework==3.11.0 # https://github.com/encode/django-rest-framework djangorestframework-simplejwt==4.5.0 # https://github.com/SimpleJWT/django-rest-framework-simplejwt drf-yasg==1.17.1 # For Api Docs django-filter==2.4.0 -django-location-field==2.1.0 # https://django-location-field.readthedocs.io/en/latest/ drf-nested-routers==0.91 django-multiselectfield==0.1.12 # https://github.com/goinnn/django-multiselectfield django-partial-index==0.6.0 # https://github.com/mattiaslinnap/django-partial-index/blob/master/README.md From da247a1c8955c282d284274380ac2d4bfcc8175a Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 14:19:45 +0530 Subject: [PATCH 03/24] remove dateparser --- care/utils/tests/test_base.py | 5 +++-- pyproject.toml | 1 - requirements/base.txt | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/care/utils/tests/test_base.py b/care/utils/tests/test_base.py index bc160026b1..1edd441567 100644 --- a/care/utils/tests/test_base.py +++ b/care/utils/tests/test_base.py @@ -3,7 +3,6 @@ from collections import OrderedDict from uuid import uuid4 -import dateparser from django.utils.timezone import make_aware from pytz import unicode from rest_framework import status @@ -347,7 +346,9 @@ def to_matching_type(name: str, value): unicode, ), ): - return_value = dateparser.parse(value) + return_value = datetime.datetime.strptime( + value, "%Y-%m-%dT%H:%M:%S.%fZ" + ) return ( return_value.astimezone(tz=datetime.timezone.utc) if isinstance(return_value, datetime.datetime) diff --git a/pyproject.toml b/pyproject.toml index ba1fa783f3..839b857557 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,6 @@ known_third_party = [ "boto3", "celery", "crispy_forms", - "dateparser", "dateutil", "django", "django_filters", diff --git a/requirements/base.txt b/requirements/base.txt index 321927c06e..3486fdb44b 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -27,7 +27,6 @@ django-fernet-fields==0.6 # https://django-fernet-fields.readthedocs.io/en/lates dry-rest-permissions==0.1.10 # For permissions handling django-cors-headers==3.2.1 django-watchman==1.1.0 # For Status Endpoints -dateparser==0.7.4 # date parsing utils django-maintenance-mode==0.14.0 # Maintenance mode django-phonenumber-field==4.0.0 phonenumberslite==8.12.1 From 65b7c867b2255df5a7713c7fad3b8a21bd39f523 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 14:19:45 +0530 Subject: [PATCH 04/24] remove django celery beat --- config/settings/base.py | 2 -- requirements/base.txt | 1 - 2 files changed, 3 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 97ad6c0f91..a547b3ffc0 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -93,7 +93,6 @@ "djangoql", "maintenance_mode", "django.contrib.postgres", - "django_celery_beat", "django_rest_passwordreset", "healthy_django", ] @@ -358,7 +357,6 @@ def GETKEY(group, request): # TODO: set to whatever value is adequate in your circumstances CELERY_TASK_SOFT_TIME_LIMIT = 1800 # http://docs.celeryproject.org/en/latest/userguide/configuration.html#beat-scheduler -# CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" CELERY_TIMEZONE = "Asia/Kolkata" CSV_REQUEST_PARAMETER = "csv" diff --git a/requirements/base.txt b/requirements/base.txt index 3486fdb44b..dabc29006d 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -45,7 +45,6 @@ newrelic # Asyncronous Part # ------------------------------------------------------------------------------ celery==4.4.2 -django-celery-beat==2.0.0 # PDF Printing Tools # ------------------------------------------------------------------------------ django-hardcopy==0.1.4 From a1197d3fa2a52f36bfedc3204479fdde52e19cc2 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 16:54:41 +0530 Subject: [PATCH 05/24] squash migrations --- .../migrations/0001_initial_squashed.py | 7099 +++++++++++++++++ .../0001_initial.py | 0 .../0002_auto_20200319_1244.py | 0 .../0003_auto_20200319_1739.py | 0 .../0004_auto_20200319_1833.py | 0 .../0005_facility_created_by.py | 0 .../0006_auto_20200320_1616.py | 0 .../0007_auto_20200320_1641.py | 0 .../0008_auto_20200320_1847.py | 0 .../0009_auto_20200320_1850.py | 0 .../0010_auto_20200321_0758.py | 0 .../0011_auto_20200321_0927.py | 0 .../0011_facility_phone_number.py | 0 .../0012_merge_20200321_1015.py | 0 .../0013_auto_20200322_1158.py | 0 .../0014_delete_facilitylocation.py | 0 .../0014_facility_oxygen_capacity.py | 0 .../0015_facility_location.py | 0 .../0016_merge_20200322_1622.py | 0 .../0017_auto_20200322_1642.py | 0 .../0018_ambulance_ambulancedriver.py | 0 .../0019_auto_20200322_2056.py | 0 .../0020_auto_20200323_1029.py | 0 .../0021_auto_20200324_0756.py | 0 .../0022_ambulance_ambulance_type.py | 0 ...entregistration_patientteleconsultation.py | 0 .../0023_merge_20200324_1959.py | 0 .../0024_auto_20200325_0311.py | 0 .../0025_auto_20200325_1908.py | 0 .../0026_map_to_district.py | 0 .../0027_auto_20200326_1015.py | 0 .../0028_auto_20200326_1705.py | 0 .../0028_auto_20200326_1752.py | 0 .../0029_auto_20200326_1706.py | 0 .../0030_auto_20200327_0619.py | 0 .../0030_merge_20200326_2047.py | 0 .../0031_rename_kasargode.py | 0 .../0032_merge_20200327_1215.py | 0 .../0033_ambulance_service_charge.py | 0 .../0034_auto_20200327_1628.py | 0 .../0034_facilitypatientstatshistory.py | 0 .../0035_auto_20200328_0442.py | 0 .../0035_building_num_buildings.py | 0 .../0035_historicalfacilitycapacity.py | 0 .../0036_patientconsultation_created_by.py | 0 .../0037_auto_20200328_1256.py | 0 .../0038_merge_20200328_1433.py | 0 .../0039_auto_20200328_1657.py | 0 .../0039_auto_20200328_1706.py | 0 .../0040_auto_20200328_1713.py | 0 .../0041_merge_20200328_1855.py | 0 .../0042_auto_20200328_2018.py | 0 .../0043_populate_facility_district.py | 0 .../0044_patientregistration_real_name.py | 0 .../0044_patientsample_patientsampleflow.py | 0 .../0045_auto_20200329_0757.py | 0 .../0046_merge_20200329_0842.py | 0 .../0047_auto_20200329_1051.py | 0 .../0048_auto_20200330_0433.py | 0 .../0049_auto_20200330_1047.py | 0 .../0050_dailyround.py | 0 .../0051_auto_20200330_1257.py | 0 ...2_remove_patientconsultation_created_by.py | 0 .../0053_delete_duplicate_diseases.py | 0 .../0054_auto_20200331_0950.py | 0 .../0055_auto_20200331_1144.py | 0 .../0056_auto_20200401_0932.py | 0 .../0057_auto_20200401_1018.py | 0 .../0058_auto_20200401_1820.py | 0 .../0059_patientsample_fast_track.py | 0 .../0060_auto_20200402_1126.py | 0 .../0061_auto_20200402_1128.py | 0 .../0062_auto_20200402_1336.py | 0 .../0062_populate_facility_in_patient.py | 0 .../0063_merge_20200402_1402.py | 0 .../0064_auto_20200402_1624.py | 0 .../0065_auto_20200402_1647.py | 0 .../0066_auto_20200402_1806.py | 0 .../0067_auto_20200402_1841.py | 0 .../0068_auto_20200402_2149.py | 0 .../0068_auto_20200403_1611.py | 0 .../0069_auto_20200402_2209.py | 0 .../0070_auto_20200402_2228.py | 0 .../0071_auto_20200404_1737.py | 0 .../0072_merge_20200404_2148.py | 0 .../0073_auto_20200404_2303.py | 0 .../0074_auto_20200404_2352.py | 0 .../0075_auto_20200405_1122.py | 0 .../0076_auto_20200409_0412.py | 0 .../0077_auto_20200409_0422.py | 0 .../0078_auto_20200409_0436.py | 0 .../0079_auto_20200409_0451.py | 0 .../0080_auto_20200409_0459.py | 0 .../0081_auto_20200409_1201.py | 0 .../0082_populate_patient_search.py | 0 .../0083_auto_20200411_1136.py | 0 .../0084_install_trigram_similarity.py | 0 .../0085_auto_20200412_0116.py | 0 .../0086_auto_20200412_1313.py | 0 .../0087_add_users_to_facility_user.py | 0 ...ationicmr_patienticmr_patientsampleicmr.py | 0 .../0089_auto_20200413_2036.py | 0 .../0090_auto_20200415_0710.py | 0 .../0091_auto_20200415_1158.py | 0 .../0092_recompute_facility_types.py | 0 .../0093_auto_20200415_1102.py | 0 .../0094_auto_20200417_1038.py | 0 .../0095_recompute_facility_types.py | 0 .../0096_auto_20200416_1414.py | 0 .../0097_auto_20200417_1404.py | 0 .../0098_auto_20200418_1302.py | 0 .../0099_auto_20200418_2030.py | 0 .../0100_auto_20200418_2315.py | 0 .../0101_populate_countries_travelled.py | 0 .../0102_auto_20200424_1508.py | 0 .../0103_auto_20200425_1440.py | 0 .../0104_populate_patient_external_ids.py | 0 .../0105_auto_20200425_1446.py | 0 .../0106_auto_20200510_1557.py | 0 .../0107_populate_external_ids.py | 0 .../0108_auto_20200510_1612.py | 0 .../0109_auto_20200511_2120.py | 0 .../0110_populate_patient_search_ids.py | 0 .../0111_auto_20200511_2123.py | 0 .../0112_auto_20200515_1738.py | 0 .../0113_auto_20200519_0005.py | 0 .../0114_auto_20200610_1720.py | 0 .../0115_auto_20200611_1336.py | 0 .../0116_facility_pincode.py | 0 .../0117_patientsample_icmr_category.py | 0 .../0118_auto_20200616_1051.py | 0 .../0119_auto_20200617_1618.py | 0 .../0120_patientsample_icmr_label.py | 0 .../0121_auto_20200619_2306.py | 0 .../0122_auto_20200624_1127.py | 0 .../0123_auto_20200626_0144.py | 0 .../0124_populate_daily_round_ids.py | 0 .../0125_auto_20200626_0146.py | 0 .../0126_auto_20200626_0156.py | 0 .../0127_patientsearch_is_active.py | 0 .../0128_facilityrelatedsummary.py | 0 .../0129_auto_20200706_1912.py | 0 .../0130_auto_20200706_1946.py | 0 .../0131_auto_20200706_1954.py | 0 .../0132_patientsample_testing_facility.py | 0 .../0133_auto_20200710_2355.py | 0 .../0134_auto_20200713_1756.py | 0 .../0135_auto_20200715_1433.py | 0 .../0136_auto_20200716_1003.py | 0 .../0137_auto_20200718_0654.py | 0 .../0138_auto_20200720_2227.py | 0 .../0139_shiftingrequest.py | 0 .../0140_auto_20200723_2355.py | 0 ...41_facilityrelatedsummary_modified_date.py | 0 .../0142_shiftingrequest_patient.py | 0 .../0143_auto_20200731_1217.py | 0 .../0144_patientmobileotp.py | 0 .../0145_auto_20200731_1913.py | 0 .../0146_auto_20200801_1844.py | 0 .../0147_auto_20200802_2134.py | 0 .../0148_populate_unencrypted_patients.py | 0 .../0149_auto_20200802_2156.py | 0 .../0150_auto_20200802_2156.py | 0 .../0151_auto_20200802_2207.py | 0 .../0152_auto_20200805_1906.py | 0 .../0153_auto_20200805_2226.py | 0 ...154_populate_patients_last_consultation.py | 0 .../0155_auto_20200805_2312.py | 0 .../0156_auto_20200808_2205.py | 0 .../0157_patientconsultation_ip_no.py | 0 .../0158_auto_20200809_1140.py | 0 ...159_patientconsultation_is_telemedicine.py | 0 .../0160_patientconsultation_doctor.py | 0 .../0161_auto_20200810_1338.py | 0 .../0162_auto_20200811_1101.py | 0 .../0163_auto_20200811_1115.py | 0 .../0164_auto_20200811_1157.py | 0 ...shistory_num_patient_confirmed_positive.py | 0 .../0166_auto_20200815_1930.py | 0 .../0167_auto_20200830_1121.py | 0 .../0168_auto_20200830_1222.py | 0 .../0169_auto_20200830_1232.py | 0 .../0170_patientconsultation_test_id.py | 0 .../0171_auto_20200901_2205.py | 0 .../0172_auto_20200903_1617.py | 0 .../0173_auto_20200903_1625.py | 0 .../0174_auto_20200903_1836.py | 0 .../0175_auto_20200904_1000.py | 0 .../0176_auto_20200916_1443.py | 0 .../0177_auto_20200916_1448.py | 0 .../0178_auto_20200916_1534.py | 0 .../0179_auto_20200918_1132.py | 0 .../0180_facility_ward.py | 0 .../0181_auto_20200921_1754.py | 0 .../0182_auto_20200921_1756.py | 0 .../0183_shiftingrequest_is_kasp.py | 0 .../0184_auto_20200925_2353.py | 0 .../0185_correct_blood_donation.py | 0 .../0186_auto_20200926_0001.py | 0 .../0187_patientexternaltest.py | 0 .../0188_auto_20200928_0139.py | 0 .../0189_auto_20200929_1258.py | 0 .../0190_auto_20201001_1134.py | 0 .../0191_dailyround_spo2.py | 0 .../0192_auto_20201004_1457.py | 0 .../0193_auto_20201004_1458.py | 0 .../0194_auto_20201009_1936.py | 0 .../0195_auto_20201009_1939.py | 0 .../0196_auto_20201011_2219.py | 0 .../0197_auto_20201011_2338.py | 0 ...198_shiftingrequest_is_assigned_to_user.py | 0 .../0199_shiftingrequest_assigned_to.py | 0 .../0200_dailyround_admitted_to.py | 0 .../0201_populate_admitted_to_daily_round.py | 0 .../0202_auto_20201024_1956.py | 0 .../0203_auto_20201024_2024.py | 0 .../0204_auto_20201024_2052.py | 0 .../0205_auto_20201025_1709.py | 0 .../0206_notification.py | 0 .../0207_auto_20201123_0056.py | 0 .../0208_notification_caused_objects.py | 0 .../0209_auto_20201123_1132.py | 0 ..._notification_caused_object_external_id.py | 0 .../0211_auto_20201214_1014.py | 0 .../0212_auto_20201223_1617.py | 0 .../0213_auto_20210107_1310.py | 0 .../0214_auto_20210129_2250.py | 0 .../0215_auto_20210130_2236.py | 0 .../0216_auto_20210201_2228.py | 0 ...investigation_patientinvestigationgroup.py | 0 .../0218_auto_20210417_2354.py | 0 ...219_remove_investigationsession_session.py | 0 .../0220_populate_investigations.py | 0 .../0221_auto_20210426_1153.py | 0 .../0221_facility_kasp_empanelled.py | 0 .../0221_investigationsession_created_by.py | 0 .../0222_auto_20210427_0002.py | 0 .../0222_auto_20210501_0958.py | 0 .../0223_merge_20210427_1419.py | 0 ...isease_status_from_recover_to_recovered.py | 2 +- ...0225_facilityinventorylog_current_stock.py | 0 ...tyinventorylog_quantity_in_default_unit.py | 0 .../0227_auto_20210505_2055.py | 0 .../0227_auto_20210506_1409.py | 0 ...28_shiftingrequest_breathlessness_level.py | 0 .../0229_merge_20210506_1549.py | 0 ...30_facility_expected_oxygen_requirement.py | 0 .../0231_auto_20210508_2214.py | 0 .../0232_auto_20210510_1218.py | 0 .../0233_auto_20210510_1832.py | 0 .../0234_auto_20210511_2058.py | 0 .../0235_merge_20210513_1316.py | 0 .../0236_auto_20210513_1336.py | 0 ...0237_dailyround_created_by_telemedicine.py | 0 .../0238_fileupload_file_category.py | 0 .../0239_patientconsultation_is_kasp.py | 0 ...0_patientconsultation_kasp_enabled_date.py | 0 .../0241_auto_20210519_0115.py | 0 .../0242_auto_20210523_1310.py | 0 .../0243_auto_20210524_2245.py | 0 .../0244_resourcerequest_title.py | 0 .../0245_auto_20210525_0130.py | 0 ..._facilityinventorylog_probable_accident.py | 0 .../0247_auto_20210526_1922.py | 0 .../0248_auto_20210529_1957.py | 0 .../0249_auto_20210529_2031.py | 0 .../0250_auto_20210603_0359.py | 0 .../0251_auto_20210607_2009.py | 0 .../0252_auto_20210609_2332.py | 0 .../0253_auto_20210612_1256.py | 0 .../0254_patientnotes.py | 0 ...tassetlocation_userdefaultassetlocation.py | 0 .../0256_assettransaction_asset.py | 0 .../0257_auto_20210618_1642.py | 0 .../0258_auto_20210623_1742.py | 0 ...259_patientexternaltest_patient_created.py | 0 .../0260_auto_20210710_1742.py | 0 .../0261_auto_20210710_2305.py | 0 .../0262_auto_20210711_0007.py | 0 .../0263_auto_20210711_1716.py | 0 .../0264_dailyround_in_prone_position.py | 0 .../0265_auto_20210712_1133.py | 0 .../0266_auto_20210717_2041.py | 0 .../0267_dailyround_meta.py | 0 .../0268_auto_20210729_1327.py | 0 ...patientconsultation_special_instruction.py | 0 .../0269_merge_20210815_1344.py | 0 .../0270_auto_20210815_1356.py | 0 .../0271_auto_20210815_1617.py | 0 .../0272_auto_20210825_1248.py | 0 .../0273_auto_20210825_1829.py | 0 .../0274_auto_20210910_1647.py | 0 .../0275_auto_20210917_1544.py | 0 .../0275_auto_20210920_1811.py | 0 .../0275_auto_20210927_2033.py | 0 .../0276_auto_20210930_1451.py | 0 .../0277_merge_20211011_2103.py | 0 .../0278_asset_not_working_reason.py | 0 .../0279_auto_20211122_1138.py | 0 .../0280_auto_20211210_0038.py | 0 .../0281_auto_20211214_1454.py | 0 .../0282_dailyround_pain.py | 0 ...82_patientconsultation_last_daily_round.py | 0 .../0283_merge_20220128_0315.py | 0 .../0284_patientconsultation_hba1c.py | 0 .../0285_asset_asset_class.py | 0 .../0286_auto_20220316_2004.py | 0 .../0287_asset_qr_code_id.py | 0 .../0287_auto_20220415_1932.py | 0 .../0288_auto_20220422_0206.py | 0 .../0288_patientconsultation_current_bed.py | 0 .../0289_merge_20220422_2220.py | 0 .../0290_auto_20220426_2231.py | 0 .../0291_facility_cover_image_url.py | 0 .../0292_auto_20220430_1748.py | 0 .../0293_auto_20220520_1941.py | 0 .../0293_facility_middleware_address.py | 0 .../0294_auto_20220523_1419.py | 0 .../0294_auto_20220526_0133.py | 0 .../0295_merge_20220527_1430.py | 0 .../0296_auto_20220527_1925.py | 0 .../0297_auto_20220619_1821.py | 0 .../0297_facility_location.py | 4 +- .../0298_auto_20220625_1627.py | 0 .../0298_facility_features.py | 0 .../0299_merge_20220704_0225.py | 0 .../0300_merge_20220707_2339.py | 0 .../0301_auto_20220709_2051.py | 0 ...02_patientconsultation_prn_prescription.py | 0 .../0303_patientconsultation_procedure.py | 0 .../0304_auto_20220726_1903.py | 0 .../0305_auto_20220730_1956.py | 0 .../0306_auto_20220803_1946.py | 0 .../0307_auto_20220805_1933.py | 0 .../0308_auto_20220805_2247.py | 0 .../0309_auto_20220818_1949.py | 0 .../0309_auto_20220820_1541.py | 0 .../0310_merge_20220820_2047.py | 0 .../0311_auto_20220824_1757.py | 0 .../0312_patientconsultation_investigation.py | 0 .../0313_auto_20220901_2213.py | 0 ...314_patientconsultation_icd11_diagnoses.py | 0 .../0315_auto_20220908_1027.py | 0 .../0315_auto_20220909_0925.py | 0 .../0315_auto_20220909_2322.py | 0 ...onsultation_icd11_provisional_diagnoses.py | 0 .../0316_auto_20220908_1112.py | 0 .../0316_auto_20220909_2331.py | 0 .../0317_merge_20220915_2209.py | 0 .../0318_merge_20220917_2113.py | 0 .../0318_merge_20220918_1241.py | 0 ...0319_dailyround_medicine_administration.py | 0 .../0319_file_upload_completed.py | 0 .../0320_merge_20220920_2114.py | 0 .../0321_merge_20220921_2255.py | 0 .../0322_fileupload_is_archived.py | 0 ...322_patientconsultation_review_interval.py | 0 .../0323_fileupload_archive_reason.py | 0 .../0324_merge_20221013_0053.py | 0 .../0325_merge_20221015_2136.py | 0 .../0326_auto_20221018_1526.py | 0 .../0327_auto_20221122_1750.py | 0 .../0327_fileupload_archived_by.py | 0 .../0328_merge_20221208_1110.py | 0 .../0329_auto_20221223_1152.py | 0 .../0330_auto_20221223_1952.py | 0 .../0331_auto_20221224_1531.py | 0 .../0332_auto_20230110_2114.py | 0 ...patientconsultation_consultation_status.py | 0 .../0333_auto_20230112_2233.py | 1 - .../0334_merge_20230113_1507.py | 0 .../0335_auto_20230207_1914.py | 0 .../0336_auto_20230222_1602.py | 0 .../0336_patientconsultation_op_no.py | 0 .../0337_metaicd11diagnosis.py | 0 ...atientconsultation_referred_to_external.py | 0 .../0338_auto_20230323_1249.py | 0 .../0339_merge_20230406_1408.py | 0 .../0340_auto_20230406_1409.py | 0 .../0341_auto_20230407_0346.py | 0 .../0342_auto_20230407_1424.py | 0 .../0343_auto_20230407_1850.py | 0 .../0344_auto_20230414_2040.py | 0 ...ftingrequest_assigned_facility_external.py | 0 .../0345_auto_20230414_2046.py | 0 .../0346_merge_20230419_0952.py | 0 .../0347_auto_20230421_1357.py | 0 .../0348_merge_20230421_1917.py | 0 .../0349_auto_20230422_2058.py | 0 .../0350_auto_20230422_2114.py | 0 .../0351_auto_20230424_1227.py | 0 .../0352_auto_20230428_1539.py | 2 +- .../0353_auto_20230429_2026.py | 0 .../0354_auto_20230519_1501.py | 0 .../0355_auto_20230429_2027.py | 2 +- .../0356_auto_20230512_1122.py | 0 .../0357_auto_20230523_1304.py | 0 .../0358_auto_20230524_1853.py | 0 .../0359_auto_20230529_1907.py | 0 .../0360_auto_20230608_1750.py | 0 care/facility/migrations_old/__init__.py | 0 care/hcx/migrations/0001_initial_squashed.py | 309 + .../0001_initial.py | 0 .../0002_claim.py | 0 .../0003_auto_20230217_1901.py | 0 .../0004_auto_20230222_2012.py | 0 .../0005_auto_20230222_2217.py | 0 .../0006_auto_20230323_1208.py | 0 care/hcx/migrations_old/__init__.py | 0 .../users/migrations/0001_initial_squashed.py | 525 ++ .../migrations/0002_auto_20230613_1622.py | 90 + .../0001_initial.py | 0 .../0002_auto_20200319_0634.py | 0 .../0003_user_verified.py | 0 .../0004_auto_20200321_0556.py | 0 .../0005_auto_20200321_0601.py | 0 .../0006_user_deleted.py | 0 .../0007_auto_20200321_2029.py | 0 .../0008_auto_20200321_2035.py | 0 .../0009_auto_20200325_1908.py | 0 .../0010_populate_district.py | 0 .../0011_map_users_to_district.py | 0 .../0012_auto_20200326_0342.py | 0 .../0012_auto_20200326_1752.py | 0 .../0013_auto_20200326_2021.py | 0 .../0013_auto_20200327_0437.py | 0 .../0014_restart_sequence_districts.py | 0 .../0015_merge_20200327_1215.py | 0 .../0016_auto_20200327_1954.py | 0 .../0017_auto_20200328_2256.py | 0 .../0018_auto_20200328_1853.py | 0 .../0019_auto_20200328_2226.py | 0 .../0020_auto_20200401_0930.py | 0 .../0021_make_kerala_everyones_state.py | 0 .../0022_auto_verify_users_with_facility.py | 0 .../0023_auto_20200413_1301.py | 0 .../0024_auto_20200801_1844.py | 0 .../0025_auto_20200914_2027.py | 0 .../0026_auto_20200914_2034.py | 0 .../0027_auto_20200914_2052.py | 0 .../0028_auto_20200916_0008.py | 0 .../0029_ward.py | 0 .../0030_auto_20200921_1659.py | 0 .../0031_auto_20200927_1325.py | 0 .../0032_user_ward.py | 0 .../0033_auto_20201011_1908.py | 0 .../0034_auto_20201122_2013.py | 0 .../0035_auto_20210511_2105.py | 0 .../0036_auto_20210515_2048.py | 0 .../0037_auto_20210519_1826.py | 0 .../0038_user_alt_phone_number.py | 0 .../0039_auto_20210616_1634.py | 0 .../0040_auto_20210616_1821.py | 0 .../0041_user_asset.py | 0 .../0042_user_created_by.py | 0 .../0043_auto_20220624_1119.py | 0 .../0044_user_home_facility.py | 0 .../0045_auto_20230110_1120.py | 0 .../0046_auto_20230204_1733.py | 0 .../0047_user_external_id.py | 0 .../0048_auto_20230609_1411.py | 0 .../0049_auto_20230609_1413.py | 0 care/users/migrations_old/__init__.py | 0 463 files changed, 8028 insertions(+), 6 deletions(-) create mode 100644 care/facility/migrations/0001_initial_squashed.py rename care/facility/{migrations => migrations_old}/0001_initial.py (100%) rename care/facility/{migrations => migrations_old}/0002_auto_20200319_1244.py (100%) rename care/facility/{migrations => migrations_old}/0003_auto_20200319_1739.py (100%) rename care/facility/{migrations => migrations_old}/0004_auto_20200319_1833.py (100%) rename care/facility/{migrations => migrations_old}/0005_facility_created_by.py (100%) rename care/facility/{migrations => migrations_old}/0006_auto_20200320_1616.py (100%) rename care/facility/{migrations => migrations_old}/0007_auto_20200320_1641.py (100%) rename care/facility/{migrations => migrations_old}/0008_auto_20200320_1847.py (100%) rename care/facility/{migrations => migrations_old}/0009_auto_20200320_1850.py (100%) rename care/facility/{migrations => migrations_old}/0010_auto_20200321_0758.py (100%) rename care/facility/{migrations => migrations_old}/0011_auto_20200321_0927.py (100%) rename care/facility/{migrations => migrations_old}/0011_facility_phone_number.py (100%) rename care/facility/{migrations => migrations_old}/0012_merge_20200321_1015.py (100%) rename care/facility/{migrations => migrations_old}/0013_auto_20200322_1158.py (100%) rename care/facility/{migrations => migrations_old}/0014_delete_facilitylocation.py (100%) rename care/facility/{migrations => migrations_old}/0014_facility_oxygen_capacity.py (100%) rename care/facility/{migrations => migrations_old}/0015_facility_location.py (100%) rename care/facility/{migrations => migrations_old}/0016_merge_20200322_1622.py (100%) rename care/facility/{migrations => migrations_old}/0017_auto_20200322_1642.py (100%) rename care/facility/{migrations => migrations_old}/0018_ambulance_ambulancedriver.py (100%) rename care/facility/{migrations => migrations_old}/0019_auto_20200322_2056.py (100%) rename care/facility/{migrations => migrations_old}/0020_auto_20200323_1029.py (100%) rename care/facility/{migrations => migrations_old}/0021_auto_20200324_0756.py (100%) rename care/facility/{migrations => migrations_old}/0022_ambulance_ambulance_type.py (100%) rename care/facility/{migrations => migrations_old}/0022_patientregistration_patientteleconsultation.py (100%) rename care/facility/{migrations => migrations_old}/0023_merge_20200324_1959.py (100%) rename care/facility/{migrations => migrations_old}/0024_auto_20200325_0311.py (100%) rename care/facility/{migrations => migrations_old}/0025_auto_20200325_1908.py (100%) rename care/facility/{migrations => migrations_old}/0026_map_to_district.py (100%) rename care/facility/{migrations => migrations_old}/0027_auto_20200326_1015.py (100%) rename care/facility/{migrations => migrations_old}/0028_auto_20200326_1705.py (100%) rename care/facility/{migrations => migrations_old}/0028_auto_20200326_1752.py (100%) rename care/facility/{migrations => migrations_old}/0029_auto_20200326_1706.py (100%) rename care/facility/{migrations => migrations_old}/0030_auto_20200327_0619.py (100%) rename care/facility/{migrations => migrations_old}/0030_merge_20200326_2047.py (100%) rename care/facility/{migrations => migrations_old}/0031_rename_kasargode.py (100%) rename care/facility/{migrations => migrations_old}/0032_merge_20200327_1215.py (100%) rename care/facility/{migrations => migrations_old}/0033_ambulance_service_charge.py (100%) rename care/facility/{migrations => migrations_old}/0034_auto_20200327_1628.py (100%) rename care/facility/{migrations => migrations_old}/0034_facilitypatientstatshistory.py (100%) rename care/facility/{migrations => migrations_old}/0035_auto_20200328_0442.py (100%) rename care/facility/{migrations => migrations_old}/0035_building_num_buildings.py (100%) rename care/facility/{migrations => migrations_old}/0035_historicalfacilitycapacity.py (100%) rename care/facility/{migrations => migrations_old}/0036_patientconsultation_created_by.py (100%) rename care/facility/{migrations => migrations_old}/0037_auto_20200328_1256.py (100%) rename care/facility/{migrations => migrations_old}/0038_merge_20200328_1433.py (100%) rename care/facility/{migrations => migrations_old}/0039_auto_20200328_1657.py (100%) rename care/facility/{migrations => migrations_old}/0039_auto_20200328_1706.py (100%) rename care/facility/{migrations => migrations_old}/0040_auto_20200328_1713.py (100%) rename care/facility/{migrations => migrations_old}/0041_merge_20200328_1855.py (100%) rename care/facility/{migrations => migrations_old}/0042_auto_20200328_2018.py (100%) rename care/facility/{migrations => migrations_old}/0043_populate_facility_district.py (100%) rename care/facility/{migrations => migrations_old}/0044_patientregistration_real_name.py (100%) rename care/facility/{migrations => migrations_old}/0044_patientsample_patientsampleflow.py (100%) rename care/facility/{migrations => migrations_old}/0045_auto_20200329_0757.py (100%) rename care/facility/{migrations => migrations_old}/0046_merge_20200329_0842.py (100%) rename care/facility/{migrations => migrations_old}/0047_auto_20200329_1051.py (100%) rename care/facility/{migrations => migrations_old}/0048_auto_20200330_0433.py (100%) rename care/facility/{migrations => migrations_old}/0049_auto_20200330_1047.py (100%) rename care/facility/{migrations => migrations_old}/0050_dailyround.py (100%) rename care/facility/{migrations => migrations_old}/0051_auto_20200330_1257.py (100%) rename care/facility/{migrations => migrations_old}/0052_remove_patientconsultation_created_by.py (100%) rename care/facility/{migrations => migrations_old}/0053_delete_duplicate_diseases.py (100%) rename care/facility/{migrations => migrations_old}/0054_auto_20200331_0950.py (100%) rename care/facility/{migrations => migrations_old}/0055_auto_20200331_1144.py (100%) rename care/facility/{migrations => migrations_old}/0056_auto_20200401_0932.py (100%) rename care/facility/{migrations => migrations_old}/0057_auto_20200401_1018.py (100%) rename care/facility/{migrations => migrations_old}/0058_auto_20200401_1820.py (100%) rename care/facility/{migrations => migrations_old}/0059_patientsample_fast_track.py (100%) rename care/facility/{migrations => migrations_old}/0060_auto_20200402_1126.py (100%) rename care/facility/{migrations => migrations_old}/0061_auto_20200402_1128.py (100%) rename care/facility/{migrations => migrations_old}/0062_auto_20200402_1336.py (100%) rename care/facility/{migrations => migrations_old}/0062_populate_facility_in_patient.py (100%) rename care/facility/{migrations => migrations_old}/0063_merge_20200402_1402.py (100%) rename care/facility/{migrations => migrations_old}/0064_auto_20200402_1624.py (100%) rename care/facility/{migrations => migrations_old}/0065_auto_20200402_1647.py (100%) rename care/facility/{migrations => migrations_old}/0066_auto_20200402_1806.py (100%) rename care/facility/{migrations => migrations_old}/0067_auto_20200402_1841.py (100%) rename care/facility/{migrations => migrations_old}/0068_auto_20200402_2149.py (100%) rename care/facility/{migrations => migrations_old}/0068_auto_20200403_1611.py (100%) rename care/facility/{migrations => migrations_old}/0069_auto_20200402_2209.py (100%) rename care/facility/{migrations => migrations_old}/0070_auto_20200402_2228.py (100%) rename care/facility/{migrations => migrations_old}/0071_auto_20200404_1737.py (100%) rename care/facility/{migrations => migrations_old}/0072_merge_20200404_2148.py (100%) rename care/facility/{migrations => migrations_old}/0073_auto_20200404_2303.py (100%) rename care/facility/{migrations => migrations_old}/0074_auto_20200404_2352.py (100%) rename care/facility/{migrations => migrations_old}/0075_auto_20200405_1122.py (100%) rename care/facility/{migrations => migrations_old}/0076_auto_20200409_0412.py (100%) rename care/facility/{migrations => migrations_old}/0077_auto_20200409_0422.py (100%) rename care/facility/{migrations => migrations_old}/0078_auto_20200409_0436.py (100%) rename care/facility/{migrations => migrations_old}/0079_auto_20200409_0451.py (100%) rename care/facility/{migrations => migrations_old}/0080_auto_20200409_0459.py (100%) rename care/facility/{migrations => migrations_old}/0081_auto_20200409_1201.py (100%) rename care/facility/{migrations => migrations_old}/0082_populate_patient_search.py (100%) rename care/facility/{migrations => migrations_old}/0083_auto_20200411_1136.py (100%) rename care/facility/{migrations => migrations_old}/0084_install_trigram_similarity.py (100%) rename care/facility/{migrations => migrations_old}/0085_auto_20200412_0116.py (100%) rename care/facility/{migrations => migrations_old}/0086_auto_20200412_1313.py (100%) rename care/facility/{migrations => migrations_old}/0087_add_users_to_facility_user.py (100%) rename care/facility/{migrations => migrations_old}/0088_patientconsultationicmr_patienticmr_patientsampleicmr.py (100%) rename care/facility/{migrations => migrations_old}/0089_auto_20200413_2036.py (100%) rename care/facility/{migrations => migrations_old}/0090_auto_20200415_0710.py (100%) rename care/facility/{migrations => migrations_old}/0091_auto_20200415_1158.py (100%) rename care/facility/{migrations => migrations_old}/0092_recompute_facility_types.py (100%) rename care/facility/{migrations => migrations_old}/0093_auto_20200415_1102.py (100%) rename care/facility/{migrations => migrations_old}/0094_auto_20200417_1038.py (100%) rename care/facility/{migrations => migrations_old}/0095_recompute_facility_types.py (100%) rename care/facility/{migrations => migrations_old}/0096_auto_20200416_1414.py (100%) rename care/facility/{migrations => migrations_old}/0097_auto_20200417_1404.py (100%) rename care/facility/{migrations => migrations_old}/0098_auto_20200418_1302.py (100%) rename care/facility/{migrations => migrations_old}/0099_auto_20200418_2030.py (100%) rename care/facility/{migrations => migrations_old}/0100_auto_20200418_2315.py (100%) rename care/facility/{migrations => migrations_old}/0101_populate_countries_travelled.py (100%) rename care/facility/{migrations => migrations_old}/0102_auto_20200424_1508.py (100%) rename care/facility/{migrations => migrations_old}/0103_auto_20200425_1440.py (100%) rename care/facility/{migrations => migrations_old}/0104_populate_patient_external_ids.py (100%) rename care/facility/{migrations => migrations_old}/0105_auto_20200425_1446.py (100%) rename care/facility/{migrations => migrations_old}/0106_auto_20200510_1557.py (100%) rename care/facility/{migrations => migrations_old}/0107_populate_external_ids.py (100%) rename care/facility/{migrations => migrations_old}/0108_auto_20200510_1612.py (100%) rename care/facility/{migrations => migrations_old}/0109_auto_20200511_2120.py (100%) rename care/facility/{migrations => migrations_old}/0110_populate_patient_search_ids.py (100%) rename care/facility/{migrations => migrations_old}/0111_auto_20200511_2123.py (100%) rename care/facility/{migrations => migrations_old}/0112_auto_20200515_1738.py (100%) rename care/facility/{migrations => migrations_old}/0113_auto_20200519_0005.py (100%) rename care/facility/{migrations => migrations_old}/0114_auto_20200610_1720.py (100%) rename care/facility/{migrations => migrations_old}/0115_auto_20200611_1336.py (100%) rename care/facility/{migrations => migrations_old}/0116_facility_pincode.py (100%) rename care/facility/{migrations => migrations_old}/0117_patientsample_icmr_category.py (100%) rename care/facility/{migrations => migrations_old}/0118_auto_20200616_1051.py (100%) rename care/facility/{migrations => migrations_old}/0119_auto_20200617_1618.py (100%) rename care/facility/{migrations => migrations_old}/0120_patientsample_icmr_label.py (100%) rename care/facility/{migrations => migrations_old}/0121_auto_20200619_2306.py (100%) rename care/facility/{migrations => migrations_old}/0122_auto_20200624_1127.py (100%) rename care/facility/{migrations => migrations_old}/0123_auto_20200626_0144.py (100%) rename care/facility/{migrations => migrations_old}/0124_populate_daily_round_ids.py (100%) rename care/facility/{migrations => migrations_old}/0125_auto_20200626_0146.py (100%) rename care/facility/{migrations => migrations_old}/0126_auto_20200626_0156.py (100%) rename care/facility/{migrations => migrations_old}/0127_patientsearch_is_active.py (100%) rename care/facility/{migrations => migrations_old}/0128_facilityrelatedsummary.py (100%) rename care/facility/{migrations => migrations_old}/0129_auto_20200706_1912.py (100%) rename care/facility/{migrations => migrations_old}/0130_auto_20200706_1946.py (100%) rename care/facility/{migrations => migrations_old}/0131_auto_20200706_1954.py (100%) rename care/facility/{migrations => migrations_old}/0132_patientsample_testing_facility.py (100%) rename care/facility/{migrations => migrations_old}/0133_auto_20200710_2355.py (100%) rename care/facility/{migrations => migrations_old}/0134_auto_20200713_1756.py (100%) rename care/facility/{migrations => migrations_old}/0135_auto_20200715_1433.py (100%) rename care/facility/{migrations => migrations_old}/0136_auto_20200716_1003.py (100%) rename care/facility/{migrations => migrations_old}/0137_auto_20200718_0654.py (100%) rename care/facility/{migrations => migrations_old}/0138_auto_20200720_2227.py (100%) rename care/facility/{migrations => migrations_old}/0139_shiftingrequest.py (100%) rename care/facility/{migrations => migrations_old}/0140_auto_20200723_2355.py (100%) rename care/facility/{migrations => migrations_old}/0141_facilityrelatedsummary_modified_date.py (100%) rename care/facility/{migrations => migrations_old}/0142_shiftingrequest_patient.py (100%) rename care/facility/{migrations => migrations_old}/0143_auto_20200731_1217.py (100%) rename care/facility/{migrations => migrations_old}/0144_patientmobileotp.py (100%) rename care/facility/{migrations => migrations_old}/0145_auto_20200731_1913.py (100%) rename care/facility/{migrations => migrations_old}/0146_auto_20200801_1844.py (100%) rename care/facility/{migrations => migrations_old}/0147_auto_20200802_2134.py (100%) rename care/facility/{migrations => migrations_old}/0148_populate_unencrypted_patients.py (100%) rename care/facility/{migrations => migrations_old}/0149_auto_20200802_2156.py (100%) rename care/facility/{migrations => migrations_old}/0150_auto_20200802_2156.py (100%) rename care/facility/{migrations => migrations_old}/0151_auto_20200802_2207.py (100%) rename care/facility/{migrations => migrations_old}/0152_auto_20200805_1906.py (100%) rename care/facility/{migrations => migrations_old}/0153_auto_20200805_2226.py (100%) rename care/facility/{migrations => migrations_old}/0154_populate_patients_last_consultation.py (100%) rename care/facility/{migrations => migrations_old}/0155_auto_20200805_2312.py (100%) rename care/facility/{migrations => migrations_old}/0156_auto_20200808_2205.py (100%) rename care/facility/{migrations => migrations_old}/0157_patientconsultation_ip_no.py (100%) rename care/facility/{migrations => migrations_old}/0158_auto_20200809_1140.py (100%) rename care/facility/{migrations => migrations_old}/0159_patientconsultation_is_telemedicine.py (100%) rename care/facility/{migrations => migrations_old}/0160_patientconsultation_doctor.py (100%) rename care/facility/{migrations => migrations_old}/0161_auto_20200810_1338.py (100%) rename care/facility/{migrations => migrations_old}/0162_auto_20200811_1101.py (100%) rename care/facility/{migrations => migrations_old}/0163_auto_20200811_1115.py (100%) rename care/facility/{migrations => migrations_old}/0164_auto_20200811_1157.py (100%) rename care/facility/{migrations => migrations_old}/0165_facilitypatientstatshistory_num_patient_confirmed_positive.py (100%) rename care/facility/{migrations => migrations_old}/0166_auto_20200815_1930.py (100%) rename care/facility/{migrations => migrations_old}/0167_auto_20200830_1121.py (100%) rename care/facility/{migrations => migrations_old}/0168_auto_20200830_1222.py (100%) rename care/facility/{migrations => migrations_old}/0169_auto_20200830_1232.py (100%) rename care/facility/{migrations => migrations_old}/0170_patientconsultation_test_id.py (100%) rename care/facility/{migrations => migrations_old}/0171_auto_20200901_2205.py (100%) rename care/facility/{migrations => migrations_old}/0172_auto_20200903_1617.py (100%) rename care/facility/{migrations => migrations_old}/0173_auto_20200903_1625.py (100%) rename care/facility/{migrations => migrations_old}/0174_auto_20200903_1836.py (100%) rename care/facility/{migrations => migrations_old}/0175_auto_20200904_1000.py (100%) rename care/facility/{migrations => migrations_old}/0176_auto_20200916_1443.py (100%) rename care/facility/{migrations => migrations_old}/0177_auto_20200916_1448.py (100%) rename care/facility/{migrations => migrations_old}/0178_auto_20200916_1534.py (100%) rename care/facility/{migrations => migrations_old}/0179_auto_20200918_1132.py (100%) rename care/facility/{migrations => migrations_old}/0180_facility_ward.py (100%) rename care/facility/{migrations => migrations_old}/0181_auto_20200921_1754.py (100%) rename care/facility/{migrations => migrations_old}/0182_auto_20200921_1756.py (100%) rename care/facility/{migrations => migrations_old}/0183_shiftingrequest_is_kasp.py (100%) rename care/facility/{migrations => migrations_old}/0184_auto_20200925_2353.py (100%) rename care/facility/{migrations => migrations_old}/0185_correct_blood_donation.py (100%) rename care/facility/{migrations => migrations_old}/0186_auto_20200926_0001.py (100%) rename care/facility/{migrations => migrations_old}/0187_patientexternaltest.py (100%) rename care/facility/{migrations => migrations_old}/0188_auto_20200928_0139.py (100%) rename care/facility/{migrations => migrations_old}/0189_auto_20200929_1258.py (100%) rename care/facility/{migrations => migrations_old}/0190_auto_20201001_1134.py (100%) rename care/facility/{migrations => migrations_old}/0191_dailyround_spo2.py (100%) rename care/facility/{migrations => migrations_old}/0192_auto_20201004_1457.py (100%) rename care/facility/{migrations => migrations_old}/0193_auto_20201004_1458.py (100%) rename care/facility/{migrations => migrations_old}/0194_auto_20201009_1936.py (100%) rename care/facility/{migrations => migrations_old}/0195_auto_20201009_1939.py (100%) rename care/facility/{migrations => migrations_old}/0196_auto_20201011_2219.py (100%) rename care/facility/{migrations => migrations_old}/0197_auto_20201011_2338.py (100%) rename care/facility/{migrations => migrations_old}/0198_shiftingrequest_is_assigned_to_user.py (100%) rename care/facility/{migrations => migrations_old}/0199_shiftingrequest_assigned_to.py (100%) rename care/facility/{migrations => migrations_old}/0200_dailyround_admitted_to.py (100%) rename care/facility/{migrations => migrations_old}/0201_populate_admitted_to_daily_round.py (100%) rename care/facility/{migrations => migrations_old}/0202_auto_20201024_1956.py (100%) rename care/facility/{migrations => migrations_old}/0203_auto_20201024_2024.py (100%) rename care/facility/{migrations => migrations_old}/0204_auto_20201024_2052.py (100%) rename care/facility/{migrations => migrations_old}/0205_auto_20201025_1709.py (100%) rename care/facility/{migrations => migrations_old}/0206_notification.py (100%) rename care/facility/{migrations => migrations_old}/0207_auto_20201123_0056.py (100%) rename care/facility/{migrations => migrations_old}/0208_notification_caused_objects.py (100%) rename care/facility/{migrations => migrations_old}/0209_auto_20201123_1132.py (100%) rename care/facility/{migrations => migrations_old}/0210_remove_notification_caused_object_external_id.py (100%) rename care/facility/{migrations => migrations_old}/0211_auto_20201214_1014.py (100%) rename care/facility/{migrations => migrations_old}/0212_auto_20201223_1617.py (100%) rename care/facility/{migrations => migrations_old}/0213_auto_20210107_1310.py (100%) rename care/facility/{migrations => migrations_old}/0214_auto_20210129_2250.py (100%) rename care/facility/{migrations => migrations_old}/0215_auto_20210130_2236.py (100%) rename care/facility/{migrations => migrations_old}/0216_auto_20210201_2228.py (100%) rename care/facility/{migrations => migrations_old}/0217_investigationsession_investigationvalue_patientinvestigation_patientinvestigationgroup.py (100%) rename care/facility/{migrations => migrations_old}/0218_auto_20210417_2354.py (100%) rename care/facility/{migrations => migrations_old}/0219_remove_investigationsession_session.py (100%) rename care/facility/{migrations => migrations_old}/0220_populate_investigations.py (100%) rename care/facility/{migrations => migrations_old}/0221_auto_20210426_1153.py (100%) rename care/facility/{migrations => migrations_old}/0221_facility_kasp_empanelled.py (100%) rename care/facility/{migrations => migrations_old}/0221_investigationsession_created_by.py (100%) rename care/facility/{migrations => migrations_old}/0222_auto_20210427_0002.py (100%) rename care/facility/{migrations => migrations_old}/0222_auto_20210501_0958.py (100%) rename care/facility/{migrations => migrations_old}/0223_merge_20210427_1419.py (100%) rename care/facility/{migrations => migrations_old}/0224_change_disease_status_from_recover_to_recovered.py (93%) rename care/facility/{migrations => migrations_old}/0225_facilityinventorylog_current_stock.py (100%) rename care/facility/{migrations => migrations_old}/0226_facilityinventorylog_quantity_in_default_unit.py (100%) rename care/facility/{migrations => migrations_old}/0227_auto_20210505_2055.py (100%) rename care/facility/{migrations => migrations_old}/0227_auto_20210506_1409.py (100%) rename care/facility/{migrations => migrations_old}/0228_shiftingrequest_breathlessness_level.py (100%) rename care/facility/{migrations => migrations_old}/0229_merge_20210506_1549.py (100%) rename care/facility/{migrations => migrations_old}/0230_facility_expected_oxygen_requirement.py (100%) rename care/facility/{migrations => migrations_old}/0231_auto_20210508_2214.py (100%) rename care/facility/{migrations => migrations_old}/0232_auto_20210510_1218.py (100%) rename care/facility/{migrations => migrations_old}/0233_auto_20210510_1832.py (100%) rename care/facility/{migrations => migrations_old}/0234_auto_20210511_2058.py (100%) rename care/facility/{migrations => migrations_old}/0235_merge_20210513_1316.py (100%) rename care/facility/{migrations => migrations_old}/0236_auto_20210513_1336.py (100%) rename care/facility/{migrations => migrations_old}/0237_dailyround_created_by_telemedicine.py (100%) rename care/facility/{migrations => migrations_old}/0238_fileupload_file_category.py (100%) rename care/facility/{migrations => migrations_old}/0239_patientconsultation_is_kasp.py (100%) rename care/facility/{migrations => migrations_old}/0240_patientconsultation_kasp_enabled_date.py (100%) rename care/facility/{migrations => migrations_old}/0241_auto_20210519_0115.py (100%) rename care/facility/{migrations => migrations_old}/0242_auto_20210523_1310.py (100%) rename care/facility/{migrations => migrations_old}/0243_auto_20210524_2245.py (100%) rename care/facility/{migrations => migrations_old}/0244_resourcerequest_title.py (100%) rename care/facility/{migrations => migrations_old}/0245_auto_20210525_0130.py (100%) rename care/facility/{migrations => migrations_old}/0246_facilityinventorylog_probable_accident.py (100%) rename care/facility/{migrations => migrations_old}/0247_auto_20210526_1922.py (100%) rename care/facility/{migrations => migrations_old}/0248_auto_20210529_1957.py (100%) rename care/facility/{migrations => migrations_old}/0249_auto_20210529_2031.py (100%) rename care/facility/{migrations => migrations_old}/0250_auto_20210603_0359.py (100%) rename care/facility/{migrations => migrations_old}/0251_auto_20210607_2009.py (100%) rename care/facility/{migrations => migrations_old}/0252_auto_20210609_2332.py (100%) rename care/facility/{migrations => migrations_old}/0253_auto_20210612_1256.py (100%) rename care/facility/{migrations => migrations_old}/0254_patientnotes.py (100%) rename care/facility/{migrations => migrations_old}/0255_asset_assetlocation_assettransaction_facilitydefaultassetlocation_userdefaultassetlocation.py (100%) rename care/facility/{migrations => migrations_old}/0256_assettransaction_asset.py (100%) rename care/facility/{migrations => migrations_old}/0257_auto_20210618_1642.py (100%) rename care/facility/{migrations => migrations_old}/0258_auto_20210623_1742.py (100%) rename care/facility/{migrations => migrations_old}/0259_patientexternaltest_patient_created.py (100%) rename care/facility/{migrations => migrations_old}/0260_auto_20210710_1742.py (100%) rename care/facility/{migrations => migrations_old}/0261_auto_20210710_2305.py (100%) rename care/facility/{migrations => migrations_old}/0262_auto_20210711_0007.py (100%) rename care/facility/{migrations => migrations_old}/0263_auto_20210711_1716.py (100%) rename care/facility/{migrations => migrations_old}/0264_dailyround_in_prone_position.py (100%) rename care/facility/{migrations => migrations_old}/0265_auto_20210712_1133.py (100%) rename care/facility/{migrations => migrations_old}/0266_auto_20210717_2041.py (100%) rename care/facility/{migrations => migrations_old}/0267_dailyround_meta.py (100%) rename care/facility/{migrations => migrations_old}/0268_auto_20210729_1327.py (100%) rename care/facility/{migrations => migrations_old}/0268_patientconsultation_special_instruction.py (100%) rename care/facility/{migrations => migrations_old}/0269_merge_20210815_1344.py (100%) rename care/facility/{migrations => migrations_old}/0270_auto_20210815_1356.py (100%) rename care/facility/{migrations => migrations_old}/0271_auto_20210815_1617.py (100%) rename care/facility/{migrations => migrations_old}/0272_auto_20210825_1248.py (100%) rename care/facility/{migrations => migrations_old}/0273_auto_20210825_1829.py (100%) rename care/facility/{migrations => migrations_old}/0274_auto_20210910_1647.py (100%) rename care/facility/{migrations => migrations_old}/0275_auto_20210917_1544.py (100%) rename care/facility/{migrations => migrations_old}/0275_auto_20210920_1811.py (100%) rename care/facility/{migrations => migrations_old}/0275_auto_20210927_2033.py (100%) rename care/facility/{migrations => migrations_old}/0276_auto_20210930_1451.py (100%) rename care/facility/{migrations => migrations_old}/0277_merge_20211011_2103.py (100%) rename care/facility/{migrations => migrations_old}/0278_asset_not_working_reason.py (100%) rename care/facility/{migrations => migrations_old}/0279_auto_20211122_1138.py (100%) rename care/facility/{migrations => migrations_old}/0280_auto_20211210_0038.py (100%) rename care/facility/{migrations => migrations_old}/0281_auto_20211214_1454.py (100%) rename care/facility/{migrations => migrations_old}/0282_dailyround_pain.py (100%) rename care/facility/{migrations => migrations_old}/0282_patientconsultation_last_daily_round.py (100%) rename care/facility/{migrations => migrations_old}/0283_merge_20220128_0315.py (100%) rename care/facility/{migrations => migrations_old}/0284_patientconsultation_hba1c.py (100%) rename care/facility/{migrations => migrations_old}/0285_asset_asset_class.py (100%) rename care/facility/{migrations => migrations_old}/0286_auto_20220316_2004.py (100%) rename care/facility/{migrations => migrations_old}/0287_asset_qr_code_id.py (100%) rename care/facility/{migrations => migrations_old}/0287_auto_20220415_1932.py (100%) rename care/facility/{migrations => migrations_old}/0288_auto_20220422_0206.py (100%) rename care/facility/{migrations => migrations_old}/0288_patientconsultation_current_bed.py (100%) rename care/facility/{migrations => migrations_old}/0289_merge_20220422_2220.py (100%) rename care/facility/{migrations => migrations_old}/0290_auto_20220426_2231.py (100%) rename care/facility/{migrations => migrations_old}/0291_facility_cover_image_url.py (100%) rename care/facility/{migrations => migrations_old}/0292_auto_20220430_1748.py (100%) rename care/facility/{migrations => migrations_old}/0293_auto_20220520_1941.py (100%) rename care/facility/{migrations => migrations_old}/0293_facility_middleware_address.py (100%) rename care/facility/{migrations => migrations_old}/0294_auto_20220523_1419.py (100%) rename care/facility/{migrations => migrations_old}/0294_auto_20220526_0133.py (100%) rename care/facility/{migrations => migrations_old}/0295_merge_20220527_1430.py (100%) rename care/facility/{migrations => migrations_old}/0296_auto_20220527_1925.py (100%) rename care/facility/{migrations => migrations_old}/0297_auto_20220619_1821.py (100%) rename care/facility/{migrations => migrations_old}/0297_facility_location.py (96%) rename care/facility/{migrations => migrations_old}/0298_auto_20220625_1627.py (100%) rename care/facility/{migrations => migrations_old}/0298_facility_features.py (100%) rename care/facility/{migrations => migrations_old}/0299_merge_20220704_0225.py (100%) rename care/facility/{migrations => migrations_old}/0300_merge_20220707_2339.py (100%) rename care/facility/{migrations => migrations_old}/0301_auto_20220709_2051.py (100%) rename care/facility/{migrations => migrations_old}/0302_patientconsultation_prn_prescription.py (100%) rename care/facility/{migrations => migrations_old}/0303_patientconsultation_procedure.py (100%) rename care/facility/{migrations => migrations_old}/0304_auto_20220726_1903.py (100%) rename care/facility/{migrations => migrations_old}/0305_auto_20220730_1956.py (100%) rename care/facility/{migrations => migrations_old}/0306_auto_20220803_1946.py (100%) rename care/facility/{migrations => migrations_old}/0307_auto_20220805_1933.py (100%) rename care/facility/{migrations => migrations_old}/0308_auto_20220805_2247.py (100%) rename care/facility/{migrations => migrations_old}/0309_auto_20220818_1949.py (100%) rename care/facility/{migrations => migrations_old}/0309_auto_20220820_1541.py (100%) rename care/facility/{migrations => migrations_old}/0310_merge_20220820_2047.py (100%) rename care/facility/{migrations => migrations_old}/0311_auto_20220824_1757.py (100%) rename care/facility/{migrations => migrations_old}/0312_patientconsultation_investigation.py (100%) rename care/facility/{migrations => migrations_old}/0313_auto_20220901_2213.py (100%) rename care/facility/{migrations => migrations_old}/0314_patientconsultation_icd11_diagnoses.py (100%) rename care/facility/{migrations => migrations_old}/0315_auto_20220908_1027.py (100%) rename care/facility/{migrations => migrations_old}/0315_auto_20220909_0925.py (100%) rename care/facility/{migrations => migrations_old}/0315_auto_20220909_2322.py (100%) rename care/facility/{migrations => migrations_old}/0315_patientconsultation_icd11_provisional_diagnoses.py (100%) rename care/facility/{migrations => migrations_old}/0316_auto_20220908_1112.py (100%) rename care/facility/{migrations => migrations_old}/0316_auto_20220909_2331.py (100%) rename care/facility/{migrations => migrations_old}/0317_merge_20220915_2209.py (100%) rename care/facility/{migrations => migrations_old}/0318_merge_20220917_2113.py (100%) rename care/facility/{migrations => migrations_old}/0318_merge_20220918_1241.py (100%) rename care/facility/{migrations => migrations_old}/0319_dailyround_medicine_administration.py (100%) rename care/facility/{migrations => migrations_old}/0319_file_upload_completed.py (100%) rename care/facility/{migrations => migrations_old}/0320_merge_20220920_2114.py (100%) rename care/facility/{migrations => migrations_old}/0321_merge_20220921_2255.py (100%) rename care/facility/{migrations => migrations_old}/0322_fileupload_is_archived.py (100%) rename care/facility/{migrations => migrations_old}/0322_patientconsultation_review_interval.py (100%) rename care/facility/{migrations => migrations_old}/0323_fileupload_archive_reason.py (100%) rename care/facility/{migrations => migrations_old}/0324_merge_20221013_0053.py (100%) rename care/facility/{migrations => migrations_old}/0325_merge_20221015_2136.py (100%) rename care/facility/{migrations => migrations_old}/0326_auto_20221018_1526.py (100%) rename care/facility/{migrations => migrations_old}/0327_auto_20221122_1750.py (100%) rename care/facility/{migrations => migrations_old}/0327_fileupload_archived_by.py (100%) rename care/facility/{migrations => migrations_old}/0328_merge_20221208_1110.py (100%) rename care/facility/{migrations => migrations_old}/0329_auto_20221223_1152.py (100%) rename care/facility/{migrations => migrations_old}/0330_auto_20221223_1952.py (100%) rename care/facility/{migrations => migrations_old}/0331_auto_20221224_1531.py (100%) rename care/facility/{migrations => migrations_old}/0332_auto_20230110_2114.py (100%) rename care/facility/{migrations => migrations_old}/0332_patientconsultation_consultation_status.py (100%) rename care/facility/{migrations => migrations_old}/0333_auto_20230112_2233.py (95%) rename care/facility/{migrations => migrations_old}/0334_merge_20230113_1507.py (100%) rename care/facility/{migrations => migrations_old}/0335_auto_20230207_1914.py (100%) rename care/facility/{migrations => migrations_old}/0336_auto_20230222_1602.py (100%) rename care/facility/{migrations => migrations_old}/0336_patientconsultation_op_no.py (100%) rename care/facility/{migrations => migrations_old}/0337_metaicd11diagnosis.py (100%) rename care/facility/{migrations => migrations_old}/0337_patientconsultation_referred_to_external.py (100%) rename care/facility/{migrations => migrations_old}/0338_auto_20230323_1249.py (100%) rename care/facility/{migrations => migrations_old}/0339_merge_20230406_1408.py (100%) rename care/facility/{migrations => migrations_old}/0340_auto_20230406_1409.py (100%) rename care/facility/{migrations => migrations_old}/0341_auto_20230407_0346.py (100%) rename care/facility/{migrations => migrations_old}/0342_auto_20230407_1424.py (100%) rename care/facility/{migrations => migrations_old}/0343_auto_20230407_1850.py (100%) rename care/facility/{migrations => migrations_old}/0344_auto_20230414_2040.py (100%) rename care/facility/{migrations => migrations_old}/0344_shiftingrequest_assigned_facility_external.py (100%) rename care/facility/{migrations => migrations_old}/0345_auto_20230414_2046.py (100%) rename care/facility/{migrations => migrations_old}/0346_merge_20230419_0952.py (100%) rename care/facility/{migrations => migrations_old}/0347_auto_20230421_1357.py (100%) rename care/facility/{migrations => migrations_old}/0348_merge_20230421_1917.py (100%) rename care/facility/{migrations => migrations_old}/0349_auto_20230422_2058.py (100%) rename care/facility/{migrations => migrations_old}/0350_auto_20230422_2114.py (100%) rename care/facility/{migrations => migrations_old}/0351_auto_20230424_1227.py (100%) rename care/facility/{migrations => migrations_old}/0352_auto_20230428_1539.py (86%) rename care/facility/{migrations => migrations_old}/0353_auto_20230429_2026.py (100%) rename care/facility/{migrations => migrations_old}/0354_auto_20230519_1501.py (100%) rename care/facility/{migrations => migrations_old}/0355_auto_20230429_2027.py (99%) rename care/facility/{migrations => migrations_old}/0356_auto_20230512_1122.py (100%) rename care/facility/{migrations => migrations_old}/0357_auto_20230523_1304.py (100%) rename care/facility/{migrations => migrations_old}/0358_auto_20230524_1853.py (100%) rename care/facility/{migrations => migrations_old}/0359_auto_20230529_1907.py (100%) rename care/facility/{migrations => migrations_old}/0360_auto_20230608_1750.py (100%) create mode 100644 care/facility/migrations_old/__init__.py create mode 100644 care/hcx/migrations/0001_initial_squashed.py rename care/hcx/{migrations => migrations_old}/0001_initial.py (100%) rename care/hcx/{migrations => migrations_old}/0002_claim.py (100%) rename care/hcx/{migrations => migrations_old}/0003_auto_20230217_1901.py (100%) rename care/hcx/{migrations => migrations_old}/0004_auto_20230222_2012.py (100%) rename care/hcx/{migrations => migrations_old}/0005_auto_20230222_2217.py (100%) rename care/hcx/{migrations => migrations_old}/0006_auto_20230323_1208.py (100%) create mode 100644 care/hcx/migrations_old/__init__.py create mode 100644 care/users/migrations/0001_initial_squashed.py create mode 100644 care/users/migrations/0002_auto_20230613_1622.py rename care/users/{migrations => migrations_old}/0001_initial.py (100%) rename care/users/{migrations => migrations_old}/0002_auto_20200319_0634.py (100%) rename care/users/{migrations => migrations_old}/0003_user_verified.py (100%) rename care/users/{migrations => migrations_old}/0004_auto_20200321_0556.py (100%) rename care/users/{migrations => migrations_old}/0005_auto_20200321_0601.py (100%) rename care/users/{migrations => migrations_old}/0006_user_deleted.py (100%) rename care/users/{migrations => migrations_old}/0007_auto_20200321_2029.py (100%) rename care/users/{migrations => migrations_old}/0008_auto_20200321_2035.py (100%) rename care/users/{migrations => migrations_old}/0009_auto_20200325_1908.py (100%) rename care/users/{migrations => migrations_old}/0010_populate_district.py (100%) rename care/users/{migrations => migrations_old}/0011_map_users_to_district.py (100%) rename care/users/{migrations => migrations_old}/0012_auto_20200326_0342.py (100%) rename care/users/{migrations => migrations_old}/0012_auto_20200326_1752.py (100%) rename care/users/{migrations => migrations_old}/0013_auto_20200326_2021.py (100%) rename care/users/{migrations => migrations_old}/0013_auto_20200327_0437.py (100%) rename care/users/{migrations => migrations_old}/0014_restart_sequence_districts.py (100%) rename care/users/{migrations => migrations_old}/0015_merge_20200327_1215.py (100%) rename care/users/{migrations => migrations_old}/0016_auto_20200327_1954.py (100%) rename care/users/{migrations => migrations_old}/0017_auto_20200328_2256.py (100%) rename care/users/{migrations => migrations_old}/0018_auto_20200328_1853.py (100%) rename care/users/{migrations => migrations_old}/0019_auto_20200328_2226.py (100%) rename care/users/{migrations => migrations_old}/0020_auto_20200401_0930.py (100%) rename care/users/{migrations => migrations_old}/0021_make_kerala_everyones_state.py (100%) rename care/users/{migrations => migrations_old}/0022_auto_verify_users_with_facility.py (100%) rename care/users/{migrations => migrations_old}/0023_auto_20200413_1301.py (100%) rename care/users/{migrations => migrations_old}/0024_auto_20200801_1844.py (100%) rename care/users/{migrations => migrations_old}/0025_auto_20200914_2027.py (100%) rename care/users/{migrations => migrations_old}/0026_auto_20200914_2034.py (100%) rename care/users/{migrations => migrations_old}/0027_auto_20200914_2052.py (100%) rename care/users/{migrations => migrations_old}/0028_auto_20200916_0008.py (100%) rename care/users/{migrations => migrations_old}/0029_ward.py (100%) rename care/users/{migrations => migrations_old}/0030_auto_20200921_1659.py (100%) rename care/users/{migrations => migrations_old}/0031_auto_20200927_1325.py (100%) rename care/users/{migrations => migrations_old}/0032_user_ward.py (100%) rename care/users/{migrations => migrations_old}/0033_auto_20201011_1908.py (100%) rename care/users/{migrations => migrations_old}/0034_auto_20201122_2013.py (100%) rename care/users/{migrations => migrations_old}/0035_auto_20210511_2105.py (100%) rename care/users/{migrations => migrations_old}/0036_auto_20210515_2048.py (100%) rename care/users/{migrations => migrations_old}/0037_auto_20210519_1826.py (100%) rename care/users/{migrations => migrations_old}/0038_user_alt_phone_number.py (100%) rename care/users/{migrations => migrations_old}/0039_auto_20210616_1634.py (100%) rename care/users/{migrations => migrations_old}/0040_auto_20210616_1821.py (100%) rename care/users/{migrations => migrations_old}/0041_user_asset.py (100%) rename care/users/{migrations => migrations_old}/0042_user_created_by.py (100%) rename care/users/{migrations => migrations_old}/0043_auto_20220624_1119.py (100%) rename care/users/{migrations => migrations_old}/0044_user_home_facility.py (100%) rename care/users/{migrations => migrations_old}/0045_auto_20230110_1120.py (100%) rename care/users/{migrations => migrations_old}/0046_auto_20230204_1733.py (100%) rename care/users/{migrations => migrations_old}/0047_user_external_id.py (100%) rename care/users/{migrations => migrations_old}/0048_auto_20230609_1411.py (100%) rename care/users/{migrations => migrations_old}/0049_auto_20230609_1413.py (100%) create mode 100644 care/users/migrations_old/__init__.py diff --git a/care/facility/migrations/0001_initial_squashed.py b/care/facility/migrations/0001_initial_squashed.py new file mode 100644 index 0000000000..ff4d9b890e --- /dev/null +++ b/care/facility/migrations/0001_initial_squashed.py @@ -0,0 +1,7099 @@ +# Generated by Django 2.2.11 on 2023-06-13 10:51 + +import uuid + +import django.contrib.postgres.fields +import django.contrib.postgres.fields.jsonb +import django.core.validators +import django.db.models.deletion +import django.utils.timezone +import fernet_fields.fields +import multiselectfield.db.fields +import partial_index +import simple_history.models +from django.conf import settings +from django.db import migrations, models + +import care.facility.models.mixins.permissions.asset +import care.facility.models.mixins.permissions.facility +import care.facility.models.mixins.permissions.patient +import care.utils.models.jsonfield +import care.utils.models.validators + + +class Migration(migrations.Migration): + initial = True + + replaces = [ + ("facility", "0001_initial"), + ("facility", "0002_auto_20200319_1244"), + ("facility", "0003_auto_20200319_1739"), + ("facility", "0004_auto_20200319_1833"), + ("facility", "0005_facility_created_by"), + ("facility", "0006_auto_20200320_1616"), + ("facility", "0007_auto_20200320_1641"), + ("facility", "0008_auto_20200320_1847"), + ("facility", "0009_auto_20200320_1850"), + ("facility", "0010_auto_20200321_0758"), + ("facility", "0011_facility_phone_number"), + ("facility", "0011_auto_20200321_0927"), + ("facility", "0012_merge_20200321_1015"), + ("facility", "0013_auto_20200322_1158"), + ("facility", "0014_delete_facilitylocation"), + ("facility", "0015_facility_location"), + ("facility", "0014_facility_oxygen_capacity"), + ("facility", "0016_merge_20200322_1622"), + ("facility", "0017_auto_20200322_1642"), + ("facility", "0018_ambulance_ambulancedriver"), + ("facility", "0019_auto_20200322_2056"), + ("facility", "0020_auto_20200323_1029"), + ("facility", "0021_auto_20200324_0756"), + ("facility", "0022_patientregistration_patientteleconsultation"), + ("facility", "0022_ambulance_ambulance_type"), + ("facility", "0023_merge_20200324_1959"), + ("facility", "0024_auto_20200325_0311"), + ("facility", "0025_auto_20200325_1908"), + ("facility", "0026_map_to_district"), + ("facility", "0027_auto_20200326_1015"), + ("facility", "0028_auto_20200326_1705"), + ("facility", "0029_auto_20200326_1706"), + ("facility", "0030_auto_20200327_0619"), + ("facility", "0031_rename_kasargode"), + ("facility", "0028_auto_20200326_1752"), + ("facility", "0030_merge_20200326_2047"), + ("facility", "0032_merge_20200327_1215"), + ("facility", "0033_ambulance_service_charge"), + ("facility", "0034_auto_20200327_1628"), + ("facility", "0035_auto_20200328_0442"), + ("facility", "0036_patientconsultation_created_by"), + ("facility", "0037_auto_20200328_1256"), + ("facility", "0035_building_num_buildings"), + ("facility", "0038_merge_20200328_1433"), + ("facility", "0039_auto_20200328_1657"), + ("facility", "0040_auto_20200328_1713"), + ("facility", "0039_auto_20200328_1706"), + ("facility", "0035_historicalfacilitycapacity"), + ("facility", "0034_facilitypatientstatshistory"), + ("facility", "0041_merge_20200328_1855"), + ("facility", "0042_auto_20200328_2018"), + ("facility", "0043_populate_facility_district"), + ("facility", "0044_patientregistration_real_name"), + ("facility", "0045_auto_20200329_0757"), + ("facility", "0044_patientsample_patientsampleflow"), + ("facility", "0046_merge_20200329_0842"), + ("facility", "0047_auto_20200329_1051"), + ("facility", "0048_auto_20200330_0433"), + ("facility", "0049_auto_20200330_1047"), + ("facility", "0050_dailyround"), + ("facility", "0051_auto_20200330_1257"), + ("facility", "0052_remove_patientconsultation_created_by"), + ("facility", "0053_delete_duplicate_diseases"), + ("facility", "0054_auto_20200331_0950"), + ("facility", "0055_auto_20200331_1144"), + ("facility", "0056_auto_20200401_0932"), + ("facility", "0057_auto_20200401_1018"), + ("facility", "0058_auto_20200401_1820"), + ("facility", "0059_patientsample_fast_track"), + ("facility", "0060_auto_20200402_1126"), + ("facility", "0061_auto_20200402_1128"), + ("facility", "0062_populate_facility_in_patient"), + ("facility", "0062_auto_20200402_1336"), + ("facility", "0063_merge_20200402_1402"), + ("facility", "0064_auto_20200402_1624"), + ("facility", "0065_auto_20200402_1647"), + ("facility", "0066_auto_20200402_1806"), + ("facility", "0067_auto_20200402_1841"), + ("facility", "0068_auto_20200402_2149"), + ("facility", "0069_auto_20200402_2209"), + ("facility", "0070_auto_20200402_2228"), + ("facility", "0071_auto_20200404_1737"), + ("facility", "0068_auto_20200403_1611"), + ("facility", "0072_merge_20200404_2148"), + ("facility", "0073_auto_20200404_2303"), + ("facility", "0074_auto_20200404_2352"), + ("facility", "0075_auto_20200405_1122"), + ("facility", "0076_auto_20200409_0412"), + ("facility", "0077_auto_20200409_0422"), + ("facility", "0078_auto_20200409_0436"), + ("facility", "0079_auto_20200409_0451"), + ("facility", "0080_auto_20200409_0459"), + ("facility", "0081_auto_20200409_1201"), + ("facility", "0082_populate_patient_search"), + ("facility", "0083_auto_20200411_1136"), + ("facility", "0084_install_trigram_similarity"), + ("facility", "0085_auto_20200412_0116"), + ("facility", "0086_auto_20200412_1313"), + ("facility", "0087_add_users_to_facility_user"), + ("facility", "0088_patientconsultationicmr_patienticmr_patientsampleicmr"), + ("facility", "0089_auto_20200413_2036"), + ("facility", "0090_auto_20200415_0710"), + ("facility", "0091_auto_20200415_1158"), + ("facility", "0092_recompute_facility_types"), + ("facility", "0093_auto_20200415_1102"), + ("facility", "0094_auto_20200417_1038"), + ("facility", "0095_recompute_facility_types"), + ("facility", "0096_auto_20200416_1414"), + ("facility", "0097_auto_20200417_1404"), + ("facility", "0098_auto_20200418_1302"), + ("facility", "0099_auto_20200418_2030"), + ("facility", "0100_auto_20200418_2315"), + ("facility", "0101_populate_countries_travelled"), + ("facility", "0102_auto_20200424_1508"), + ("facility", "0103_auto_20200425_1440"), + ("facility", "0104_populate_patient_external_ids"), + ("facility", "0105_auto_20200425_1446"), + ("facility", "0106_auto_20200510_1557"), + ("facility", "0107_populate_external_ids"), + ("facility", "0108_auto_20200510_1612"), + ("facility", "0109_auto_20200511_2120"), + ("facility", "0110_populate_patient_search_ids"), + ("facility", "0111_auto_20200511_2123"), + ("facility", "0112_auto_20200515_1738"), + ("facility", "0113_auto_20200519_0005"), + ("facility", "0114_auto_20200610_1720"), + ("facility", "0115_auto_20200611_1336"), + ("facility", "0116_facility_pincode"), + ("facility", "0117_patientsample_icmr_category"), + ("facility", "0118_auto_20200616_1051"), + ("facility", "0119_auto_20200617_1618"), + ("facility", "0120_patientsample_icmr_label"), + ("facility", "0121_auto_20200619_2306"), + ("facility", "0122_auto_20200624_1127"), + ("facility", "0123_auto_20200626_0144"), + ("facility", "0124_populate_daily_round_ids"), + ("facility", "0125_auto_20200626_0146"), + ("facility", "0126_auto_20200626_0156"), + ("facility", "0127_patientsearch_is_active"), + ("facility", "0128_facilityrelatedsummary"), + ("facility", "0129_auto_20200706_1912"), + ("facility", "0130_auto_20200706_1946"), + ("facility", "0131_auto_20200706_1954"), + ("facility", "0132_patientsample_testing_facility"), + ("facility", "0133_auto_20200710_2355"), + ("facility", "0134_auto_20200713_1756"), + ("facility", "0135_auto_20200715_1433"), + ("facility", "0136_auto_20200716_1003"), + ("facility", "0137_auto_20200718_0654"), + ("facility", "0138_auto_20200720_2227"), + ("facility", "0139_shiftingrequest"), + ("facility", "0140_auto_20200723_2355"), + ("facility", "0141_facilityrelatedsummary_modified_date"), + ("facility", "0142_shiftingrequest_patient"), + ("facility", "0143_auto_20200731_1217"), + ("facility", "0144_patientmobileotp"), + ("facility", "0145_auto_20200731_1913"), + ("facility", "0146_auto_20200801_1844"), + ("facility", "0147_auto_20200802_2134"), + ("facility", "0148_populate_unencrypted_patients"), + ("facility", "0149_auto_20200802_2156"), + ("facility", "0150_auto_20200802_2156"), + ("facility", "0151_auto_20200802_2207"), + ("facility", "0152_auto_20200805_1906"), + ("facility", "0153_auto_20200805_2226"), + ("facility", "0154_populate_patients_last_consultation"), + ("facility", "0155_auto_20200805_2312"), + ("facility", "0156_auto_20200808_2205"), + ("facility", "0157_patientconsultation_ip_no"), + ("facility", "0158_auto_20200809_1140"), + ("facility", "0159_patientconsultation_is_telemedicine"), + ("facility", "0160_patientconsultation_doctor"), + ("facility", "0161_auto_20200810_1338"), + ("facility", "0162_auto_20200811_1101"), + ("facility", "0163_auto_20200811_1115"), + ("facility", "0164_auto_20200811_1157"), + ("facility", "0165_facilitypatientstatshistory_num_patient_confirmed_positive"), + ("facility", "0166_auto_20200815_1930"), + ("facility", "0167_auto_20200830_1121"), + ("facility", "0168_auto_20200830_1222"), + ("facility", "0169_auto_20200830_1232"), + ("facility", "0170_patientconsultation_test_id"), + ("facility", "0171_auto_20200901_2205"), + ("facility", "0172_auto_20200903_1617"), + ("facility", "0173_auto_20200903_1625"), + ("facility", "0174_auto_20200903_1836"), + ("facility", "0175_auto_20200904_1000"), + ("facility", "0176_auto_20200916_1443"), + ("facility", "0177_auto_20200916_1448"), + ("facility", "0178_auto_20200916_1534"), + ("facility", "0179_auto_20200918_1132"), + ("facility", "0180_facility_ward"), + ("facility", "0181_auto_20200921_1754"), + ("facility", "0182_auto_20200921_1756"), + ("facility", "0183_shiftingrequest_is_kasp"), + ("facility", "0184_auto_20200925_2353"), + ("facility", "0185_correct_blood_donation"), + ("facility", "0186_auto_20200926_0001"), + ("facility", "0187_patientexternaltest"), + ("facility", "0188_auto_20200928_0139"), + ("facility", "0189_auto_20200929_1258"), + ("facility", "0190_auto_20201001_1134"), + ("facility", "0191_dailyround_spo2"), + ("facility", "0192_auto_20201004_1457"), + ("facility", "0193_auto_20201004_1458"), + ("facility", "0194_auto_20201009_1936"), + ("facility", "0195_auto_20201009_1939"), + ("facility", "0196_auto_20201011_2219"), + ("facility", "0197_auto_20201011_2338"), + ("facility", "0198_shiftingrequest_is_assigned_to_user"), + ("facility", "0199_shiftingrequest_assigned_to"), + ("facility", "0200_dailyround_admitted_to"), + ("facility", "0201_populate_admitted_to_daily_round"), + ("facility", "0202_auto_20201024_1956"), + ("facility", "0203_auto_20201024_2024"), + ("facility", "0204_auto_20201024_2052"), + ("facility", "0205_auto_20201025_1709"), + ("facility", "0206_notification"), + ("facility", "0207_auto_20201123_0056"), + ("facility", "0208_notification_caused_objects"), + ("facility", "0209_auto_20201123_1132"), + ("facility", "0210_remove_notification_caused_object_external_id"), + ("facility", "0211_auto_20201214_1014"), + ("facility", "0212_auto_20201223_1617"), + ("facility", "0213_auto_20210107_1310"), + ("facility", "0214_auto_20210129_2250"), + ("facility", "0215_auto_20210130_2236"), + ("facility", "0216_auto_20210201_2228"), + ( + "facility", + "0217_investigationsession_investigationvalue_patientinvestigation_patientinvestigationgroup", + ), + ("facility", "0218_auto_20210417_2354"), + ("facility", "0219_remove_investigationsession_session"), + ("facility", "0220_populate_investigations"), + ("facility", "0221_auto_20210426_1153"), + ("facility", "0222_auto_20210427_0002"), + ("facility", "0221_investigationsession_created_by"), + ("facility", "0221_facility_kasp_empanelled"), + ("facility", "0223_merge_20210427_1419"), + ("facility", "0224_change_disease_status_from_recover_to_recovered"), + ("facility", "0225_facilityinventorylog_current_stock"), + ("facility", "0226_facilityinventorylog_quantity_in_default_unit"), + ("facility", "0227_auto_20210506_1409"), + ("facility", "0228_shiftingrequest_breathlessness_level"), + ("facility", "0227_auto_20210505_2055"), + ("facility", "0229_merge_20210506_1549"), + ("facility", "0230_facility_expected_oxygen_requirement"), + ("facility", "0231_auto_20210508_2214"), + ("facility", "0232_auto_20210510_1218"), + ("facility", "0233_auto_20210510_1832"), + ("facility", "0234_auto_20210511_2058"), + ("facility", "0222_auto_20210501_0958"), + ("facility", "0235_merge_20210513_1316"), + ("facility", "0236_auto_20210513_1336"), + ("facility", "0237_dailyround_created_by_telemedicine"), + ("facility", "0238_fileupload_file_category"), + ("facility", "0239_patientconsultation_is_kasp"), + ("facility", "0240_patientconsultation_kasp_enabled_date"), + ("facility", "0241_auto_20210519_0115"), + ("facility", "0242_auto_20210523_1310"), + ("facility", "0243_auto_20210524_2245"), + ("facility", "0244_resourcerequest_title"), + ("facility", "0245_auto_20210525_0130"), + ("facility", "0246_facilityinventorylog_probable_accident"), + ("facility", "0247_auto_20210526_1922"), + ("facility", "0248_auto_20210529_1957"), + ("facility", "0249_auto_20210529_2031"), + ("facility", "0250_auto_20210603_0359"), + ("facility", "0251_auto_20210607_2009"), + ("facility", "0252_auto_20210609_2332"), + ("facility", "0253_auto_20210612_1256"), + ("facility", "0254_patientnotes"), + ( + "facility", + "0255_asset_assetlocation_assettransaction_facilitydefaultassetlocation_userdefaultassetlocation", + ), + ("facility", "0256_assettransaction_asset"), + ("facility", "0257_auto_20210618_1642"), + ("facility", "0258_auto_20210623_1742"), + ("facility", "0259_patientexternaltest_patient_created"), + ("facility", "0260_auto_20210710_1742"), + ("facility", "0261_auto_20210710_2305"), + ("facility", "0262_auto_20210711_0007"), + ("facility", "0263_auto_20210711_1716"), + ("facility", "0264_dailyround_in_prone_position"), + ("facility", "0265_auto_20210712_1133"), + ("facility", "0266_auto_20210717_2041"), + ("facility", "0267_dailyround_meta"), + ("facility", "0268_patientconsultation_special_instruction"), + ("facility", "0268_auto_20210729_1327"), + ("facility", "0269_merge_20210815_1344"), + ("facility", "0270_auto_20210815_1356"), + ("facility", "0271_auto_20210815_1617"), + ("facility", "0272_auto_20210825_1248"), + ("facility", "0273_auto_20210825_1829"), + ("facility", "0274_auto_20210910_1647"), + ("facility", "0275_auto_20210917_1544"), + ("facility", "0276_auto_20210930_1451"), + ("facility", "0275_auto_20210927_2033"), + ("facility", "0275_auto_20210920_1811"), + ("facility", "0277_merge_20211011_2103"), + ("facility", "0278_asset_not_working_reason"), + ("facility", "0279_auto_20211122_1138"), + ("facility", "0280_auto_20211210_0038"), + ("facility", "0281_auto_20211214_1454"), + ("facility", "0282_patientconsultation_last_daily_round"), + ("facility", "0282_dailyround_pain"), + ("facility", "0283_merge_20220128_0315"), + ("facility", "0284_patientconsultation_hba1c"), + ("facility", "0285_asset_asset_class"), + ("facility", "0286_auto_20220316_2004"), + ("facility", "0287_auto_20220415_1932"), + ("facility", "0288_patientconsultation_current_bed"), + ("facility", "0287_asset_qr_code_id"), + ("facility", "0288_auto_20220422_0206"), + ("facility", "0289_merge_20220422_2220"), + ("facility", "0290_auto_20220426_2231"), + ("facility", "0291_facility_cover_image_url"), + ("facility", "0292_auto_20220430_1748"), + ("facility", "0293_auto_20220520_1941"), + ("facility", "0294_auto_20220526_0133"), + ("facility", "0293_facility_middleware_address"), + ("facility", "0294_auto_20220523_1419"), + ("facility", "0295_merge_20220527_1430"), + ("facility", "0296_auto_20220527_1925"), + ("facility", "0297_auto_20220619_1821"), + ("facility", "0298_facility_features"), + ("facility", "0298_auto_20220625_1627"), + ("facility", "0299_merge_20220704_0225"), + ("facility", "0297_facility_location"), + ("facility", "0300_merge_20220707_2339"), + ("facility", "0301_auto_20220709_2051"), + ("facility", "0302_patientconsultation_prn_prescription"), + ("facility", "0303_patientconsultation_procedure"), + ("facility", "0304_auto_20220726_1903"), + ("facility", "0305_auto_20220730_1956"), + ("facility", "0306_auto_20220803_1946"), + ("facility", "0307_auto_20220805_1933"), + ("facility", "0308_auto_20220805_2247"), + ("facility", "0309_auto_20220820_1541"), + ("facility", "0309_auto_20220818_1949"), + ("facility", "0310_merge_20220820_2047"), + ("facility", "0311_auto_20220824_1757"), + ("facility", "0312_patientconsultation_investigation"), + ("facility", "0313_auto_20220901_2213"), + ("facility", "0314_patientconsultation_icd11_diagnoses"), + ("facility", "0315_auto_20220908_1027"), + ("facility", "0316_auto_20220908_1112"), + ("facility", "0315_patientconsultation_icd11_provisional_diagnoses"), + ("facility", "0317_merge_20220915_2209"), + ("facility", "0315_auto_20220909_0925"), + ("facility", "0318_merge_20220917_2113"), + ("facility", "0319_dailyround_medicine_administration"), + ("facility", "0318_merge_20220918_1241"), + ("facility", "0320_merge_20220920_2114"), + ("facility", "0319_file_upload_completed"), + ("facility", "0321_merge_20220921_2255"), + ("facility", "0322_fileupload_is_archived"), + ("facility", "0323_fileupload_archive_reason"), + ("facility", "0322_patientconsultation_review_interval"), + ("facility", "0324_merge_20221013_0053"), + ("facility", "0315_auto_20220909_2322"), + ("facility", "0316_auto_20220909_2331"), + ("facility", "0325_merge_20221015_2136"), + ("facility", "0326_auto_20221018_1526"), + ("facility", "0327_fileupload_archived_by"), + ("facility", "0327_auto_20221122_1750"), + ("facility", "0328_merge_20221208_1110"), + ("facility", "0329_auto_20221223_1152"), + ("facility", "0330_auto_20221223_1952"), + ("facility", "0331_auto_20221224_1531"), + ("facility", "0332_auto_20230110_2114"), + ("facility", "0333_auto_20230112_2233"), + ("facility", "0332_patientconsultation_consultation_status"), + ("facility", "0334_merge_20230113_1507"), + ("facility", "0335_auto_20230207_1914"), + ("facility", "0336_auto_20230222_1602"), + ("facility", "0337_patientconsultation_referred_to_external"), + ("facility", "0338_auto_20230323_1249"), + ("facility", "0336_patientconsultation_op_no"), + ("facility", "0339_merge_20230406_1408"), + ("facility", "0340_auto_20230406_1409"), + ("facility", "0341_auto_20230407_0346"), + ("facility", "0342_auto_20230407_1424"), + ("facility", "0343_auto_20230407_1850"), + ("facility", "0344_auto_20230414_2040"), + ("facility", "0345_auto_20230414_2046"), + ("facility", "0337_metaicd11diagnosis"), + ("facility", "0346_merge_20230419_0952"), + ("facility", "0347_auto_20230421_1357"), + ("facility", "0344_shiftingrequest_assigned_facility_external"), + ("facility", "0348_merge_20230421_1917"), + ("facility", "0349_auto_20230422_2058"), + ("facility", "0350_auto_20230422_2114"), + ("facility", "0351_auto_20230424_1227"), + ("facility", "0352_auto_20230428_1539"), + ("facility", "0353_auto_20230429_2026"), + ("facility", "0354_auto_20230519_1501"), + ("facility", "0355_auto_20230429_2027"), + ("facility", "0356_auto_20230512_1122"), + ("facility", "0357_auto_20230523_1304"), + ("facility", "0358_auto_20230524_1853"), + ("facility", "0359_auto_20230529_1907"), + ("facility", "0360_auto_20230608_1750"), + ] + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("users", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Ambulance", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "vehicle_number", + models.CharField( + db_index=True, + max_length=20, + unique=True, + validators=[ + django.core.validators.RegexValidator( + code="invalid_vehicle_number", + message="Please Enter the vehicle number in all uppercase without spaces, eg: KL13AB1234", + regex="^[A-Z]{2}[0-9]{1,2}[A-Z]{0,2}[0-9]{1,4}$", + ) + ], + ), + ), + ("owner_name", models.CharField(max_length=255)), + ( + "owner_phone_number", + models.CharField( + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("owner_is_smart_phone", models.BooleanField(default=True)), + ("has_oxygen", models.BooleanField()), + ("has_ventilator", models.BooleanField()), + ("has_suction_machine", models.BooleanField()), + ("has_defibrillator", models.BooleanField()), + ( + "insurance_valid_till_year", + models.IntegerField( + choices=[(2020, 2020), (2021, 2021), (2022, 2022)] + ), + ), + ( + "ambulance_type", + models.IntegerField( + choices=[(1, "Basic"), (2, "Cardiac"), (3, "Hearse")], default=1 + ), + ), + ( + "price_per_km", + models.DecimalField(decimal_places=2, max_digits=7, null=True), + ), + ("has_free_service", models.BooleanField(default=False)), + ( + "created_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "primary_district", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="primary_ambulances", + to="users.District", + ), + ), + ( + "secondary_district", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="secondary_ambulances", + to="users.District", + ), + ), + ( + "third_district", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="third_ambulances", + to="users.District", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Asset", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=1024)), + ("description", models.TextField(blank=True, default="", null=True)), + ( + "asset_type", + models.IntegerField( + choices=[(50, "INTERNAL"), (100, "EXTERNAL")], default=50 + ), + ), + ( + "asset_class", + models.CharField( + blank=True, + choices=[ + ("ONVIF", "onvif"), + ("HL7MONITOR", "hl7monitor"), + ("VENTILATOR", "ventilator"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ( + "status", + models.IntegerField( + choices=[(50, "ACTIVE"), (100, "TRANSFER_IN_PROGRESS")], + default=50, + ), + ), + ( + "is_working", + models.BooleanField(blank=True, default=None, null=True), + ), + ( + "not_working_reason", + models.CharField(blank=True, max_length=1024, null=True), + ), + ( + "serial_number", + models.CharField(blank=True, max_length=1024, null=True), + ), + ( + "warranty_details", + models.TextField(blank=True, default="", null=True), + ), + ( + "meta", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + {"$ref": "#/definitions/onvif"}, + {"$ref": "#/definitions/hl7monitor"}, + {"$ref": "#/definitions/empty"}, + ], + "definitions": { + "empty": { + "additionalProperties": False, + "type": "object", + }, + "hl7monitor": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "insecure_connection": { + "type": "boolean" + }, + "local_ip_address": {"type": "string"}, + "middleware_hostname": { + "type": "string" + }, + }, + "required": ["local_ip_address"], + "type": "object", + }, + "onvif": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "camera_access_key": {"type": "string"}, + "camera_type": {"type": "string"}, + "insecure_connection": { + "type": "boolean" + }, + "local_ip_address": {"type": "string"}, + "middleware_hostname": { + "type": "string" + }, + }, + "required": [ + "local_ip_address", + "camera_access_key", + ], + "type": "object", + }, + "ventilator": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "insecure_connection": { + "type": "boolean" + }, + "local_ip_address": {"type": "string"}, + "middleware_hostname": { + "type": "string" + }, + }, + "required": ["local_ip_address"], + "type": "object", + }, + }, + } + ) + ], + ), + ), + ( + "vendor_name", + models.CharField(blank=True, max_length=1024, null=True), + ), + ( + "support_name", + models.CharField(blank=True, max_length=1024, null=True), + ), + ( + "support_phone", + models.CharField( + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile/landline/tollfree number", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}|1800\\d{6,7}$", + ) + ], + ), + ), + ( + "support_email", + models.EmailField(blank=True, max_length=254, null=True), + ), + ( + "qr_code_id", + models.CharField( + blank=True, default=None, max_length=1024, null=True + ), + ), + ( + "manufacturer", + models.CharField(blank=True, max_length=1024, null=True), + ), + ( + "warranty_amc_end_of_validity", + models.DateField(blank=True, default=None, null=True), + ), + ( + "last_serviced_on", + models.DateField(blank=True, default=None, null=True), + ), + ("notes", models.TextField(blank=True, default="", null=True)), + ], + ), + migrations.CreateModel( + name="AssetBed", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "meta", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict + ), + ), + ( + "asset", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.Asset" + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="AssetLocation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=1024)), + ("description", models.TextField(blank=True, default="", null=True)), + ( + "location_type", + models.IntegerField(choices=[(1, "OTHER"), (10, "ICU")], default=1), + ), + ], + options={ + "abstract": False, + }, + bases=( + models.Model, + care.facility.models.mixins.permissions.asset.AssetsPermissionMixin, + ), + ), + migrations.CreateModel( + name="Bed", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=1024)), + ("description", models.TextField(blank=True, default="")), + ( + "bed_type", + models.IntegerField( + choices=[ + (1, "ISOLATION"), + (2, "ICU"), + (3, "ICU_WITH_NON_INVASIVE_VENTILATOR"), + (4, "ICU_WITH_OXYGEN_SUPPORT"), + (5, "ICU_WITH_INVASIVE_VENTILATOR"), + (6, "BED_WITH_OXYGEN_SUPPORT"), + (7, "REGULAR"), + ], + default=7, + ), + ), + ( + "meta", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict + ), + ), + ( + "assets", + models.ManyToManyField( + through="facility.AssetBed", to="facility.Asset" + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Building", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=1000)), + ( + "num_rooms", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "num_floors", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "num_buildings", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="ConsultationBed", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("start_date", models.DateTimeField()), + ("end_date", models.DateTimeField(blank=True, default=None, null=True)), + ( + "meta", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict + ), + ), + ( + "bed", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.Bed" + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="DailyRound", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "temperature", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=5, + null=True, + validators=[ + django.core.validators.MinValueValidator(95), + django.core.validators.MaxValueValidator(106), + ], + ), + ), + ( + "spo2", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=4, + null=True, + ), + ), + ( + "temperature_measured_at", + models.DateTimeField(blank=True, null=True), + ), + ("physical_examination_info", models.TextField(blank=True, null=True)), + ( + "additional_symptoms", + multiselectfield.db.fields.MultiSelectField( + blank=True, + choices=[ + (1, "ASYMPTOMATIC"), + (2, "FEVER"), + (3, "SORE THROAT"), + (4, "COUGH"), + (5, "BREATHLESSNESS"), + (6, "MYALGIA"), + (7, "ABDOMINAL DISCOMFORT"), + (8, "VOMITING"), + (9, "OTHERS"), + (11, "SPUTUM"), + (12, "NAUSEA"), + (13, "CHEST PAIN"), + (14, "HEMOPTYSIS"), + (15, "NASAL DISCHARGE"), + (16, "BODY ACHE"), + (17, "DIARRHOEA"), + (18, "PAIN"), + (19, "PEDAL EDEMA"), + (20, "WOUND"), + (21, "CONSTIPATION"), + (22, "HEAD ACHE"), + (23, "BLEEDING"), + (24, "DIZZINESS"), + ], + default=1, + max_length=59, + null=True, + ), + ), + ("other_symptoms", models.TextField(blank=True, default="")), + ( + "deprecated_covid_category", + models.CharField( + blank=True, + choices=[ + ("ASYM", "ASYMPTOMATIC"), + ("Mild", "Category-A"), + ("Moderate", "Category-B"), + ("Severe", "Category-C"), + (None, "UNCLASSIFIED"), + ], + default=None, + max_length=8, + null=True, + ), + ), + ( + "patient_category", + models.CharField( + choices=[ + ("Comfort", "Comfort Care"), + ("Stable", "Stable"), + ("Moderate", "Abnormal"), + ("Critical", "Critical"), + ], + max_length=8, + null=True, + ), + ), + ( + "current_health", + models.IntegerField( + blank=True, + choices=[ + (0, "NO DATA"), + (1, "REQUIRES VENTILATOR"), + (2, "WORSE"), + (3, "STATUS QUO"), + (4, "BETTER"), + ], + default=0, + ), + ), + ( + "recommend_discharge", + models.BooleanField( + default=False, verbose_name="Recommend Discharging Patient" + ), + ), + ("other_details", models.TextField(blank=True, null=True)), + ( + "medication_given", + django.contrib.postgres.fields.jsonb.JSONField(default=dict), + ), + ("last_updated_by_telemedicine", models.BooleanField(default=False)), + ("created_by_telemedicine", models.BooleanField(default=False)), + ( + "taken_at", + models.DateTimeField(blank=True, db_index=True, null=True), + ), + ( + "rounds_type", + models.IntegerField( + choices=[ + (0, "NORMAL"), + (100, "VENTILATOR"), + (200, "ICU"), + (300, "AUTOMATED"), + ], + default=0, + ), + ), + ( + "consciousness_level", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "ALERT"), + (10, "DROWSY"), + (15, "STUPOROUS"), + (20, "COMATOSE"), + (25, "CANNOT_BE_ASSESSED"), + ], + default=0, + ), + ), + ( + "consciousness_level_detail", + models.TextField(blank=True, default=None, null=True), + ), + ( + "in_prone_position", + models.BooleanField(blank=True, default=None, null=True), + ), + ( + "left_pupil_size", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(8), + ], + verbose_name="Left Pupil Size", + ), + ), + ( + "left_pupil_size_detail", + models.TextField(blank=True, default=None, null=True), + ), + ( + "left_pupil_light_reaction", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "BRISK"), + (10, "SLUGGISH"), + (15, "FIXED"), + (20, "CANNOT_BE_ASSESSED"), + ], + default=0, + ), + ), + ( + "left_pupil_light_reaction_detail", + models.TextField(blank=True, default=None, null=True), + ), + ( + "right_pupil_size", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(8), + ], + verbose_name="Right Pupil Size", + ), + ), + ( + "right_pupil_size_detail", + models.TextField(blank=True, default=None, null=True), + ), + ( + "right_pupil_light_reaction", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "BRISK"), + (10, "SLUGGISH"), + (15, "FIXED"), + (20, "CANNOT_BE_ASSESSED"), + ], + default=0, + ), + ), + ( + "right_pupil_light_reaction_detail", + models.TextField(blank=True, default=None, null=True), + ), + ( + "glasgow_eye_open", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(4), + ], + ), + ), + ( + "glasgow_verbal_response", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(5), + ], + ), + ), + ( + "glasgow_motor_response", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(6), + ], + ), + ), + ( + "glasgow_total_calculated", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(3), + django.core.validators.MaxValueValidator(15), + ], + ), + ), + ( + "limb_response_upper_extremity_right", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "STRONG"), + (10, "MODERATE"), + (15, "WEAK"), + (20, "FLEXION"), + (25, "EXTENSION"), + (30, "NONE"), + ], + default=0, + ), + ), + ( + "limb_response_upper_extremity_left", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "STRONG"), + (10, "MODERATE"), + (15, "WEAK"), + (20, "FLEXION"), + (25, "EXTENSION"), + (30, "NONE"), + ], + default=0, + ), + ), + ( + "limb_response_lower_extremity_left", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "STRONG"), + (10, "MODERATE"), + (15, "WEAK"), + (20, "FLEXION"), + (25, "EXTENSION"), + (30, "NONE"), + ], + default=0, + ), + ), + ( + "limb_response_lower_extremity_right", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "STRONG"), + (10, "MODERATE"), + (15, "WEAK"), + (20, "FLEXION"), + (25, "EXTENSION"), + (30, "NONE"), + ], + default=0, + ), + ), + ( + "bp", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": False, + "properties": { + "diastolic": {"type": "number"}, + "mean": {"type": "number"}, + "systolic": {"type": "number"}, + }, + "type": "object", + } + ) + ], + ), + ), + ( + "pulse", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(200), + ], + ), + ), + ( + "resp", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(10), + django.core.validators.MaxValueValidator(70), + ], + ), + ), + ( + "rhythm", + models.IntegerField( + choices=[(0, "UNKNOWN"), (5, "REGULAR"), (10, "IRREGULAR")], + default=0, + ), + ), + ( + "rhythm_detail", + models.TextField(blank=True, default=None, null=True), + ), + ( + "ventilator_interface", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "INVASIVE"), + (10, "NON_INVASIVE"), + (15, "OXYGEN_SUPPORT"), + ], + default=0, + ), + ), + ( + "ventilator_mode", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "VCV"), + (10, "PCV"), + (15, "PRVC"), + (20, "APRV"), + (25, "VC_SIMV"), + (30, "PC_SIMV"), + (40, "PRVC_SIMV"), + (45, "ASV"), + (50, "PSV"), + ], + default=0, + ), + ), + ( + "ventilator_peep", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=4, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(30), + ], + ), + ), + ( + "ventilator_pip", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + ), + ), + ( + "ventilator_mean_airway_pressure", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(40), + ], + ), + ), + ( + "ventilator_resp_rate", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + ), + ), + ( + "ventilator_pressure_support", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(40), + ], + ), + ), + ( + "ventilator_tidal_volume", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(1000), + ], + ), + ), + ( + "ventilator_oxygen_modality", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (5, "NASAL_PRONGS"), + (10, "SIMPLE_FACE_MASK"), + (15, "NON_REBREATHING_MASK"), + (20, "HIGH_FLOW_NASAL_CANNULA"), + ], + default=0, + ), + ), + ( + "ventilator_oxygen_modality_oxygen_rate", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(50), + ], + ), + ), + ( + "ventilator_oxygen_modality_flow_rate", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(70), + ], + ), + ), + ( + "ventilator_fi02", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(21), + django.core.validators.MaxValueValidator(100), + ], + ), + ), + ( + "ventilator_spo2", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + ), + ), + ( + "etco2", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(200), + ], + ), + ), + ( + "bilateral_air_entry", + models.BooleanField(blank=True, default=None, null=True), + ), + ( + "pain", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(10), + ], + ), + ), + ( + "pain_scale_enhanced", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "region": {"type": "string"}, + "scale": { + "maximum": 5, + "minimum": 1, + "type": "number", + }, + }, + "required": ["region", "scale"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "ph", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=4, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(10), + ], + ), + ), + ( + "pco2", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(10), + django.core.validators.MaxValueValidator(200), + ], + ), + ), + ( + "po2", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(10), + django.core.validators.MaxValueValidator(400), + ], + ), + ), + ( + "hco3", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=4, + null=True, + validators=[ + django.core.validators.MinValueValidator(5), + django.core.validators.MaxValueValidator(80), + ], + ), + ), + ( + "base_excess", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(-20), + django.core.validators.MaxValueValidator(20), + ], + ), + ), + ( + "lactate", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=4, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(20), + ], + ), + ), + ( + "sodium", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=5, + null=True, + validators=[ + django.core.validators.MinValueValidator(100), + django.core.validators.MaxValueValidator(170), + ], + ), + ), + ( + "potassium", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=4, + null=True, + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(10), + ], + ), + ), + ( + "blood_sugar_level", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(700), + ], + ), + ), + ( + "insulin_intake_dose", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=5, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + ), + ), + ( + "insulin_intake_frequency", + models.IntegerField( + choices=[(0, "UNKNOWN"), (5, "OD"), (10, "BD"), (15, "TD")], + default=0, + ), + ), + ( + "infusions", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "conc_unit": {"type": "string"}, + "concentration": {"type": "number"}, + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "iv_fluids", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "feeds", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "calories": {"type": "number"}, + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "total_intake_calculated", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=6, + null=True, + ), + ), + ( + "output", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "total_output_calculated", + models.DecimalField( + blank=True, + decimal_places=2, + default=None, + max_digits=6, + null=True, + ), + ), + ( + "dialysis_fluid_balance", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(5000), + ], + ), + ), + ( + "dialysis_net_balance", + models.IntegerField( + default=None, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(5000), + ], + ), + ), + ( + "pressure_sore", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "base_score": {"type": "number"}, + "description": {"type": "string"}, + "exudate_amount": { + "enum": [ + "None", + "Light", + "Moderate", + "Heavy", + ] + }, + "length": {"type": "number"}, + "push_score": {"type": "number"}, + "region": {"type": "string"}, + "scale": { + "maximum": 5, + "minimum": 1, + "type": "number", + }, + "tissue_type": { + "enum": [ + "Closed", + "Epithelial", + "Granulation", + "Slough", + "Necrotic", + ] + }, + "width": {"type": "number"}, + }, + "required": [], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "nursing", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "procedure": {"type": "string"}, + }, + "required": ["procedure", "description"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ( + "medicine_administration", + django.contrib.postgres.fields.jsonb.JSONField(default=list), + ), + ( + "meta", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": False, + "properties": {"dialysis": {"type": "boolean"}}, + "type": "object", + } + ) + ], + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Facility", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=1000)), + ("is_active", models.BooleanField(default=True)), + ("verified", models.BooleanField(default=False)), + ( + "facility_type", + models.IntegerField( + choices=[ + (1, "Educational Inst"), + (2, "Private Hospital"), + (3, "Other"), + (4, "Hostel"), + (5, "Hotel"), + (6, "Lodge"), + (7, "TeleMedicine"), + (8, "Govt Hospital"), + (9, "Labs"), + (800, "Primary Health Centres"), + (801, "24x7 Public Health Centres"), + (802, "Family Health Centres"), + (803, "Community Health Centres"), + (820, "Urban Primary Health Center"), + (830, "Taluk Hospitals"), + (831, "Taluk Headquarters Hospitals"), + (840, "Women and Child Health Centres"), + (850, "General hospitals"), + (860, "District Hospitals"), + (870, "Govt Medical College Hospitals"), + (900, "Co-operative hospitals"), + (910, "Autonomous healthcare facility"), + (950, "Corona Testing Labs"), + (1000, "Corona Care Centre"), + (1010, "COVID-19 Domiciliary Care Center"), + (1100, "First Line Treatment Centre"), + (1200, "Second Line Treatment Center"), + (1300, "Shifting Centre"), + (1400, "Covid Management Center"), + (1500, "Request Approving Center"), + (1510, "Request Fulfilment Center"), + (1600, "District War Room"), + ] + ), + ), + ("kasp_empanelled", models.BooleanField(default=False)), + ( + "features", + multiselectfield.db.fields.MultiSelectField( + blank=True, + choices=[ + (1, "CT Scan Facility"), + (2, "Maternity Care"), + (3, "X-Ray facility"), + (4, "Neonatal care"), + (5, "Operation theater"), + (6, "Blood Bank"), + ], + max_length=11, + null=True, + ), + ), + ( + "longitude", + models.DecimalField( + blank=True, decimal_places=16, max_digits=22, null=True + ), + ), + ( + "latitude", + models.DecimalField( + blank=True, decimal_places=16, max_digits=22, null=True + ), + ), + ("pincode", models.IntegerField(default=None, null=True)), + ("address", models.TextField()), + ("oxygen_capacity", models.IntegerField(default=0)), + ("type_b_cylinders", models.IntegerField(default=0)), + ("type_c_cylinders", models.IntegerField(default=0)), + ("type_d_cylinders", models.IntegerField(default=0)), + ("expected_oxygen_requirement", models.IntegerField(default=0)), + ("expected_type_b_cylinders", models.IntegerField(default=0)), + ("expected_type_c_cylinders", models.IntegerField(default=0)), + ("expected_type_d_cylinders", models.IntegerField(default=0)), + ( + "phone_number", + models.CharField( + blank=True, + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("corona_testing", models.BooleanField(default=False)), + ( + "cover_image_url", + models.CharField( + blank=True, default=None, max_length=500, null=True + ), + ), + ( + "middleware_address", + models.CharField(default=None, max_length=200, null=True), + ), + ( + "created_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "district", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.District", + ), + ), + ( + "local_body", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.LocalBody", + ), + ), + ( + "state", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.State", + ), + ), + ], + options={ + "verbose_name_plural": "Facilities", + }, + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityPermissionMixin, + ), + ), + migrations.CreateModel( + name="FacilityInventoryItem", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=1000)), + ("description", models.TextField(blank=True)), + ("min_quantity", models.FloatField()), + ], + ), + migrations.CreateModel( + name="FacilityInventoryItemTag", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="FacilityInventoryUnit", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255, unique=True)), + ], + ), + migrations.CreateModel( + name="Inventory", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "quantitiy", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ], + options={ + "verbose_name_plural": "Inventories", + }, + ), + migrations.CreateModel( + name="InventoryItem", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=1000)), + ("description", models.TextField()), + ( + "minimum_stock", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ("unit", models.CharField(max_length=20)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="InvestigationSession", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_by", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="MetaICD11Diagnosis", + fields=[ + ( + "id", + models.CharField(max_length=255, primary_key=True, serialize=False), + ), + ("_id", models.IntegerField()), + ("average_depth", models.IntegerField()), + ("is_adopted_child", models.BooleanField()), + ("parent_id", models.CharField(max_length=255, null=True)), + ("class_kind", models.CharField(max_length=255)), + ("is_leaf", models.BooleanField()), + ("label", models.CharField(max_length=255)), + ( + "breadth_value", + models.DecimalField(decimal_places=22, max_digits=24), + ), + ], + options={ + "db_table": "meta_icd11_diagnosis", + }, + ), + migrations.CreateModel( + name="PatientConsultation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "ip_no", + models.CharField(blank=True, default="", max_length=100, null=True), + ), + ( + "op_no", + models.CharField(blank=True, default="", max_length=100, null=True), + ), + ("diagnosis", models.TextField(blank=True, default="", null=True)), + ( + "icd11_provisional_diagnoses", + django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(max_length=100), + blank=True, + default=[], + null=True, + size=None, + ), + ), + ( + "icd11_diagnoses", + django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(max_length=100), + blank=True, + default=[], + null=True, + size=None, + ), + ), + ( + "symptoms", + multiselectfield.db.fields.MultiSelectField( + blank=True, + choices=[ + (1, "ASYMPTOMATIC"), + (2, "FEVER"), + (3, "SORE THROAT"), + (4, "COUGH"), + (5, "BREATHLESSNESS"), + (6, "MYALGIA"), + (7, "ABDOMINAL DISCOMFORT"), + (8, "VOMITING"), + (9, "OTHERS"), + (11, "SPUTUM"), + (12, "NAUSEA"), + (13, "CHEST PAIN"), + (14, "HEMOPTYSIS"), + (15, "NASAL DISCHARGE"), + (16, "BODY ACHE"), + (17, "DIARRHOEA"), + (18, "PAIN"), + (19, "PEDAL EDEMA"), + (20, "WOUND"), + (21, "CONSTIPATION"), + (22, "HEAD ACHE"), + (23, "BLEEDING"), + (24, "DIZZINESS"), + ], + default=1, + max_length=59, + null=True, + ), + ), + ("other_symptoms", models.TextField(blank=True, default="")), + ("symptoms_onset_date", models.DateTimeField(blank=True, null=True)), + ( + "deprecated_covid_category", + models.CharField( + blank=True, + choices=[ + ("ASYM", "ASYMPTOMATIC"), + ("Mild", "Category-A"), + ("Moderate", "Category-B"), + ("Severe", "Category-C"), + (None, "UNCLASSIFIED"), + ], + default=None, + max_length=8, + null=True, + ), + ), + ( + "category", + models.CharField( + choices=[ + ("Comfort", "Comfort Care"), + ("Stable", "Stable"), + ("Moderate", "Abnormal"), + ("Critical", "Critical"), + ], + max_length=8, + null=True, + ), + ), + ("examination_details", models.TextField(blank=True, null=True)), + ("history_of_present_illness", models.TextField(blank=True, null=True)), + ("prescribed_medication", models.TextField(blank=True, null=True)), + ("consultation_notes", models.TextField(blank=True, null=True)), + ("course_in_facility", models.TextField(blank=True, null=True)), + ( + "investigation", + django.contrib.postgres.fields.jsonb.JSONField(default=dict), + ), + ( + "prescriptions", + django.contrib.postgres.fields.jsonb.JSONField(default=dict), + ), + ( + "procedure", + django.contrib.postgres.fields.jsonb.JSONField(default=dict), + ), + ( + "suggestion", + models.CharField( + choices=[ + ("HI", "HOME ISOLATION"), + ("A", "ADMISSION"), + ("R", "REFERRAL"), + ("OP", "OP CONSULTATION"), + ("DC", "DOMICILIARY CARE"), + ("DD", "DECLARE DEATH"), + ], + max_length=4, + ), + ), + ( + "consultation_status", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (1, "BROUGHT_DEAD"), + (2, "TRANSFERRED_FROM_WARD"), + (3, "TRANSFERRED_FROM_ICU"), + (4, "REFERRED_FROM_OTHER_HOSPITAL"), + (5, "OUT_PATIENT"), + ], + default=0, + ), + ), + ("review_interval", models.IntegerField(default=-1)), + ( + "referred_to_external", + models.TextField(blank=True, default="", null=True), + ), + ("admitted", models.BooleanField(default=False)), + ("admission_date", models.DateTimeField(blank=True, null=True)), + ("discharge_date", models.DateTimeField(blank=True, null=True)), + ( + "discharge_reason", + models.CharField( + blank=True, + choices=[ + ("REC", "Recovered"), + ("REF", "Referred"), + ("EXP", "Expired"), + ("LAMA", "LAMA"), + ], + default=None, + max_length=4, + null=True, + ), + ), + ( + "discharge_notes", + models.TextField(blank=True, default="", null=True), + ), + ( + "discharge_prescription", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict, null=True + ), + ), + ( + "discharge_prn_prescription", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict, null=True + ), + ), + ("death_datetime", models.DateTimeField(blank=True, null=True)), + ( + "death_confirmed_doctor", + models.TextField(blank=True, default="", null=True), + ), + ("bed_number", models.CharField(blank=True, max_length=100, null=True)), + ("is_kasp", models.BooleanField(default=False)), + ( + "kasp_enabled_date", + models.DateTimeField(blank=True, default=None, null=True), + ), + ("is_telemedicine", models.BooleanField(default=False)), + ("last_updated_by_telemedicine", models.BooleanField(default=False)), + ("verified_by", models.TextField(blank=True, default="", null=True)), + ( + "height", + models.FloatField( + default=None, + null=True, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Patient's Height in CM", + ), + ), + ( + "weight", + models.FloatField( + default=None, + null=True, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Patient's Weight in KG", + ), + ), + ( + "HBA1C", + models.FloatField( + default=None, + null=True, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="HBA1C parameter for reference to current blood sugar levels", + ), + ), + ("operation", models.TextField(blank=True, default=None, null=True)), + ( + "special_instruction", + models.TextField(blank=True, default=None, null=True), + ), + ( + "intubation_history", + django.contrib.postgres.fields.jsonb.JSONField(default=list), + ), + ( + "prn_prescription", + django.contrib.postgres.fields.jsonb.JSONField(default=dict), + ), + ( + "discharge_advice", + django.contrib.postgres.fields.jsonb.JSONField(default=dict), + ), + ( + "assigned_to", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="patient_assigned_to", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="created_user", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "current_bed", + models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="facility.ConsultationBed", + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="consultations", + to="facility.Facility", + ), + ), + ( + "last_daily_round", + models.ForeignKey( + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.DailyRound", + ), + ), + ( + "last_edited_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="last_edited_user", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + bases=( + models.Model, + care.facility.models.mixins.permissions.patient.PatientRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="PatientInvestigationGroup", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=500)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientMetaInfo", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "occupation", + models.IntegerField( + choices=[ + (1, "STUDENT"), + (2, "MEDICAL_WORKER"), + (3, "GOVT_EMPLOYEE"), + (4, "PRIVATE_EMPLOYEE"), + (5, "HOME_MAKER"), + (6, "WORKING_ABROAD"), + (7, "OTHERS"), + ] + ), + ), + ("head_of_household", models.BooleanField()), + ], + ), + migrations.CreateModel( + name="PatientMobileOTP", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("is_used", models.BooleanField(default=False)), + ( + "phone_number", + models.CharField( + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("otp", models.CharField(max_length=10)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientRegistration", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "source", + models.IntegerField( + choices=[(10, "CARE"), (20, "COVID_TRACKER"), (30, "STAY")], + default=10, + ), + ), + ("name", models.CharField(default="", max_length=200)), + ("age", models.PositiveIntegerField(blank=True, null=True)), + ( + "gender", + models.IntegerField( + choices=[(1, "Male"), (2, "Female"), (3, "Non-binary")] + ), + ), + ( + "phone_number", + models.CharField( + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ( + "emergency_phone_number", + models.CharField( + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("address", models.TextField(default="")), + ("permanent_address", models.TextField(default="")), + ("pincode", models.IntegerField(blank=True, default=0, null=True)), + ("date_of_birth", models.DateField(default=None, null=True)), + ("year_of_birth", models.IntegerField(default=0, null=True)), + ( + "nationality", + models.CharField( + default="", + max_length=255, + verbose_name="Nationality of Patient", + ), + ), + ( + "passport_no", + models.CharField( + default="", + max_length=255, + verbose_name="Passport Number of Foreign Patients", + ), + ), + ( + "is_medical_worker", + models.BooleanField( + default=False, verbose_name="Is the Patient a Medical Worker" + ), + ), + ( + "blood_group", + models.CharField( + choices=[ + ("A+", "A+"), + ("A-", "A-"), + ("B+", "B+"), + ("B-", "B-"), + ("AB+", "AB+"), + ("AB-", "AB-"), + ("O+", "O+"), + ("O-", "O-"), + ("UNK", "UNKNOWN"), + ], + max_length=4, + null=True, + verbose_name="Blood Group of Patient", + ), + ), + ( + "contact_with_confirmed_carrier", + models.BooleanField( + default=False, + verbose_name="Confirmed Contact with a Covid19 Carrier", + ), + ), + ( + "contact_with_suspected_carrier", + models.BooleanField( + default=False, + verbose_name="Suspected Contact with a Covid19 Carrier", + ), + ), + ("estimated_contact_date", models.DateTimeField(blank=True, null=True)), + ( + "past_travel", + models.BooleanField( + default=False, + verbose_name="Travelled to Any Foreign Countries in the last 28 Days", + ), + ), + ( + "countries_travelled_old", + models.TextField( + blank=True, + editable=False, + null=True, + verbose_name="Countries Patient has Travelled to", + ), + ), + ( + "countries_travelled", + care.utils.models.jsonfield.JSONField( + blank=True, + null=True, + verbose_name="Countries Patient has Travelled to", + ), + ), + ( + "date_of_return", + models.DateTimeField( + blank=True, + null=True, + verbose_name="Return Date from the Last Country if Travelled", + ), + ), + ( + "allergies", + models.TextField( + blank=True, default="", verbose_name="Patient's Known Allergies" + ), + ), + ( + "present_health", + models.TextField( + blank=True, + default="", + verbose_name="Patient's Current Health Details", + ), + ), + ( + "ongoing_medication", + models.TextField( + blank=True, + default="", + verbose_name="Already pescribed medication if any", + ), + ), + ( + "has_SARI", + models.BooleanField( + default=False, verbose_name="Does the Patient Suffer from SARI" + ), + ), + ( + "is_antenatal", + models.BooleanField( + default=None, + verbose_name="Does the patient require Prenatal Care ?", + ), + ), + ( + "ward_old", + models.CharField( + default="", max_length=255, verbose_name="Ward of Patient" + ), + ), + ( + "is_migrant_worker", + models.BooleanField( + default=False, verbose_name="Is Patient a Migrant Worker" + ), + ), + ( + "disease_status", + models.IntegerField( + blank=True, + choices=[ + (1, "SUSPECTED"), + (2, "POSITIVE"), + (3, "NEGATIVE"), + (4, "RECOVERY"), + (5, "RECOVERED"), + (6, "EXPIRED"), + ], + default=1, + verbose_name="Disease Status", + ), + ), + ( + "number_of_aged_dependents", + models.IntegerField( + blank=True, + default=0, + verbose_name="Number of people aged above 60 living with the patient", + ), + ), + ( + "number_of_chronic_diseased_dependents", + models.IntegerField( + blank=True, + default=0, + verbose_name="Number of people who have chronic diseases living with the patient", + ), + ), + ( + "action", + models.IntegerField( + blank=True, + choices=[ + (10, "NO_ACTION"), + (20, "PENDING"), + (30, "SPECIALIST_REQUIRED"), + (40, "PLAN_FOR_HOME_CARE"), + (50, "FOLLOW_UP_NOT_REQUIRED"), + (60, "COMPLETE"), + (70, "REVIEW"), + (80, "NOT_REACHABLE"), + ], + default=10, + null=True, + ), + ), + ( + "review_time", + models.DateTimeField( + blank=True, null=True, verbose_name="Patient's next review time" + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Not active when discharged, or removed from the watchlist", + ), + ), + ( + "patient_search_id", + fernet_fields.fields.EncryptedIntegerField( + help_text="FKey to PatientSearch", null=True + ), + ), + ( + "date_of_receipt_of_information", + models.DateTimeField( + blank=True, + null=True, + verbose_name="Patient's information received date", + ), + ), + ( + "test_id", + models.CharField(blank=True, default="", max_length=100, null=True), + ), + ( + "date_of_test", + models.DateTimeField( + blank=True, null=True, verbose_name="Patient's test Date" + ), + ), + ("srf_id", models.CharField(blank=True, default="", max_length=200)), + ( + "test_type", + models.IntegerField( + choices=[ + (10, "UNK"), + (20, "ANTIGEN"), + (30, "RTPCR"), + (40, "CBNAAT"), + (50, "TRUENAT"), + (60, "RTLAMP"), + (70, "POCPCR"), + ], + default=10, + ), + ), + ("allow_transfer", models.BooleanField(default=False)), + ( + "will_donate_blood", + models.BooleanField( + default=None, + null=True, + verbose_name="Is Patient Willing to donate Blood", + ), + ), + ( + "fit_for_blood_donation", + models.BooleanField( + default=None, + null=True, + verbose_name="Is Patient fit for donating Blood", + ), + ), + ( + "village", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Vilalge Name of Patient (IDSP Req)", + ), + ), + ( + "designation_of_health_care_worker", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Designation of Health Care Worker (IDSP Req)", + ), + ), + ( + "instituion_of_health_care_worker", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Institution of Healtcare Worker (IDSP Req)", + ), + ), + ( + "transit_details", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Transit Details (IDSP Req)", + ), + ), + ( + "frontline_worker", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Front Line Worker (IDSP Req)", + ), + ), + ( + "date_of_result", + models.DateTimeField( + blank=True, + default=None, + null=True, + verbose_name="Patient's result Date", + ), + ), + ( + "number_of_primary_contacts", + models.IntegerField( + blank=True, + default=None, + null=True, + verbose_name="Number of Primary Contacts", + ), + ), + ( + "number_of_secondary_contacts", + models.IntegerField( + blank=True, + default=None, + null=True, + verbose_name="Number of Secondary Contacts", + ), + ), + ( + "is_vaccinated", + models.BooleanField( + default=False, + verbose_name="Is the Patient Vaccinated Against COVID-19", + ), + ), + ( + "number_of_doses", + models.PositiveIntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(3), + ], + ), + ), + ( + "vaccine_name", + models.CharField( + choices=[ + ("CoviShield", "COVISHIELD"), + ("Covaxin", "COVAXIN"), + ("Sputnik", "SPUTNIK"), + ("Moderna", "MODERNA"), + ("Pfizer", "PFIZER"), + ("Janssen", "JANSSEN"), + ("Sinovac", "SINOVAC"), + ], + default=None, + max_length=15, + null=True, + ), + ), + ( + "covin_id", + models.CharField( + blank=True, + default=None, + max_length=15, + null=True, + verbose_name="COVID-19 Vaccination ID", + ), + ), + ( + "last_vaccinated_date", + models.DateTimeField( + blank=True, null=True, verbose_name="Date Last Vaccinated" + ), + ), + ( + "cluster_name", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Name/ Cluster of Contact", + ), + ), + ( + "is_declared_positive", + models.BooleanField( + default=None, + null=True, + verbose_name="Is Patient Declared Positive", + ), + ), + ( + "date_declared_positive", + models.DateTimeField( + blank=True, + null=True, + verbose_name="Date Patient is Declared Positive", + ), + ), + ( + "assigned_to", + models.ForeignKey( + blank="True", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="root_patient_assigned_to", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="patient_created_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "district", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.District", + ), + ), + ( + "facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.Facility", + ), + ), + ( + "last_consultation", + models.ForeignKey( + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.PatientConsultation", + ), + ), + ( + "last_edited", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="patient_last_edited_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "local_body", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.LocalBody", + ), + ), + ( + "meta_info", + models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.PatientMetaInfo", + ), + ), + ( + "nearest_facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="nearest_facility", + to="facility.Facility", + ), + ), + ( + "state", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.State", + ), + ), + ( + "ward", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.Ward", + ), + ), + ], + options={ + "abstract": False, + }, + bases=( + models.Model, + care.facility.models.mixins.permissions.patient.PatientPermissionMixin, + ), + ), + migrations.CreateModel( + name="PatientSample", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "sample_type", + models.IntegerField( + choices=[ + (0, "UNKNOWN"), + (1, "BA/ETA"), + (2, "TS/NPS/NS"), + (3, "Blood in EDTA"), + (4, "Acute Sera"), + (5, "Covalescent sera"), + (6, "Biopsy"), + (7, "AMR"), + (8, "Communicable Diseases"), + (9, "OTHER TYPE"), + ], + default=0, + ), + ), + ("sample_type_other", models.TextField(default="")), + ("has_sari", models.BooleanField(default=False)), + ("has_ari", models.BooleanField(default=False)), + ( + "doctor_name", + models.CharField(default="NO DOCTOR SPECIFIED", max_length=255), + ), + ("diagnosis", models.TextField(default="")), + ("diff_diagnosis", models.TextField(default="")), + ("etiology_identified", models.TextField(default="")), + ("is_atypical_presentation", models.BooleanField(default=False)), + ("atypical_presentation", models.TextField(default="")), + ("is_unusual_course", models.BooleanField(default=False)), + ( + "icmr_category", + models.IntegerField( + choices=[ + (0, "Cat 0"), + (10, "Cat 1"), + (20, "Cat 2"), + (30, "Cat 3"), + (40, "Cat 4"), + (50, "Cat 5a"), + (60, "Cat 5b"), + ], + default=0, + ), + ), + ("icmr_label", models.CharField(default="", max_length=200)), + ( + "status", + models.IntegerField( + choices=[ + (1, "REQUEST_SUBMITTED"), + (2, "APPROVED"), + (3, "DENIED"), + (4, "SENT_TO_COLLECTON_CENTRE"), + (5, "RECEIVED_AND_FORWARED"), + (6, "RECEIVED_AT_LAB"), + (7, "COMPLETED"), + ], + default=1, + ), + ), + ( + "result", + models.IntegerField( + choices=[ + (1, "POSITIVE"), + (2, "NEGATIVE"), + (3, "AWAITING"), + (4, "INVALID"), + ], + default=3, + ), + ), + ("fast_track", models.TextField(default="")), + ("date_of_sample", models.DateTimeField(blank=True, null=True)), + ("date_of_result", models.DateTimeField(blank=True, null=True)), + ( + "consultation", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientConsultation", + ), + ), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="samples_created", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "last_edited_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="last_edited_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientRegistration", + ), + ), + ( + "testing_facility", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.Facility", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="ResourceRequest", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("emergency", models.BooleanField(default=False)), + ("title", models.CharField(max_length=255)), + ("reason", models.TextField(blank=True, default="")), + ( + "refering_facility_contact_name", + models.TextField(blank=True, default=""), + ), + ( + "refering_facility_contact_number", + models.CharField( + blank=True, + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ( + "status", + models.IntegerField( + choices=[ + (10, "PENDING"), + (15, "ON HOLD"), + (20, "APPROVED"), + (30, "REJECTED"), + (55, "TRANSPORTATION TO BE ARRANGED"), + (70, "TRANSFER IN PROGRESS"), + (80, "COMPLETED"), + ], + default=10, + ), + ), + ( + "category", + models.IntegerField( + choices=[(100, "OXYGEN"), (200, "SUPPLIES")], default=100 + ), + ), + ( + "sub_category", + models.IntegerField( + choices=[ + (110, "LIQUID OXYGEN"), + (120, "B TYPE OXYGEN CYLINDER"), + (130, "C TYPE OXYGEN CYLINDER"), + (140, "JUMBO D TYPE OXYGEN CYLINDER"), + (1000, "UNSPECIFIED"), + ], + default=1000, + ), + ), + ("priority", models.IntegerField(blank=True, default=None, null=True)), + ("requested_quantity", models.IntegerField(default=0)), + ("assigned_quantity", models.IntegerField(default=0)), + ("is_assigned_to_user", models.BooleanField(default=False)), + ( + "approving_facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="resource_approving_facility", + to="facility.Facility", + ), + ), + ( + "assigned_facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="resource_assigned_facility", + to="facility.Facility", + ), + ), + ( + "assigned_to", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="resource_request_assigned_to", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="resource_request_created_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "last_edited_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="resource_request_last_edited_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "orgin_facility", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="resource_requesting_facility", + to="facility.Facility", + ), + ), + ], + ), + migrations.CreateModel( + name="Room", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("num", models.CharField(max_length=1000)), + ( + "floor", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "beds_capacity", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "occupied_beds", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "room_type", + models.IntegerField( + choices=[ + (0, "Total"), + (2, "Hostel"), + (3, "Single Room with Attached Bathroom"), + (40, "KASP Beds"), + (50, "KASP ICU beds"), + (60, "KASP Oxygen beds"), + (70, "KASP Ventilator beds"), + (1, "General Bed"), + (10, "ICU"), + (20, "Ventilator"), + (30, "Covid Beds"), + (100, "Covid Ventilators"), + (110, "Covid ICU"), + (120, "Covid Oxygen beds"), + (150, "Oxygen beds"), + ] + ), + ), + ( + "building", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Building", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="ShiftingRequest", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "assigned_facility_type", + models.IntegerField( + blank=True, + choices=[ + (1, "Educational Inst"), + (2, "Private Hospital"), + (3, "Other"), + (4, "Hostel"), + (5, "Hotel"), + (6, "Lodge"), + (7, "TeleMedicine"), + (8, "Govt Hospital"), + (9, "Labs"), + (800, "Primary Health Centres"), + (801, "24x7 Public Health Centres"), + (802, "Family Health Centres"), + (803, "Community Health Centres"), + (820, "Urban Primary Health Center"), + (830, "Taluk Hospitals"), + (831, "Taluk Headquarters Hospitals"), + (840, "Women and Child Health Centres"), + (850, "General hospitals"), + (860, "District Hospitals"), + (870, "Govt Medical College Hospitals"), + (900, "Co-operative hospitals"), + (910, "Autonomous healthcare facility"), + (950, "Corona Testing Labs"), + (1000, "Corona Care Centre"), + (1010, "COVID-19 Domiciliary Care Center"), + (1100, "First Line Treatment Centre"), + (1200, "Second Line Treatment Center"), + (1300, "Shifting Centre"), + (1400, "Covid Management Center"), + (1500, "Request Approving Center"), + (1510, "Request Fulfilment Center"), + (1600, "District War Room"), + ], + default=None, + null=True, + ), + ), + ( + "assigned_facility_external", + models.TextField(blank=True, default="", null=True), + ), + ("emergency", models.BooleanField(default=False)), + ("is_up_shift", models.BooleanField(default=False)), + ("reason", models.TextField(blank=True, default="")), + ("vehicle_preference", models.TextField(blank=True, default="")), + ( + "preferred_vehicle_choice", + models.IntegerField( + blank=True, + choices=[ + (10, "D Level Ambulance"), + (20, "All double chambered Ambulance with EMT"), + (30, "Ambulance without EMT"), + (40, "Car"), + (50, "Auto-rickshaw"), + ], + default=None, + null=True, + ), + ), + ("comments", models.TextField(blank=True, default="")), + ( + "refering_facility_contact_name", + models.TextField(blank=True, default=""), + ), + ( + "refering_facility_contact_number", + models.CharField( + blank=True, + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("is_kasp", models.BooleanField(default=False)), + ( + "status", + models.IntegerField( + choices=[ + (10, "PENDING"), + (15, "ON HOLD"), + (20, "APPROVED"), + (30, "REJECTED"), + (40, "DESTINATION APPROVED"), + (50, "DESTINATION REJECTED"), + (55, "TRANSPORTATION TO BE ARRANGED"), + (60, "PATIENT TO BE PICKED UP"), + (70, "TRANSFER IN PROGRESS"), + (80, "COMPLETED"), + (90, "PATIENT EXPIRED"), + (100, "CANCELLED"), + ], + default=10, + ), + ), + ( + "breathlessness_level", + models.IntegerField( + blank=True, + choices=[ + (10, "NOT SPECIFIED"), + (15, "NOT BREATHLESS"), + (20, "MILD"), + (30, "MODERATE"), + (40, "SEVERE"), + ], + default=10, + null=True, + ), + ), + ("is_assigned_to_user", models.BooleanField(default=False)), + ("ambulance_driver_name", models.TextField(blank=True, default="")), + ( + "ambulance_phone_number", + models.CharField( + blank=True, + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("ambulance_number", models.TextField(blank=True, default="")), + ( + "assigned_facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="assigned_facility", + to="facility.Facility", + ), + ), + ( + "assigned_to", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="shifting_assigned_to", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="shifting_created_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "last_edited_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="shifting_last_edited_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "orgin_facility", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="requesting_facility", + to="facility.Facility", + ), + ), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="patient", + to="facility.PatientRegistration", + ), + ), + ( + "shifting_approving_facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="shifting_approving_facility", + to="facility.Facility", + ), + ), + ], + ), + migrations.CreateModel( + name="UserDefaultAssetLocation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "location", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.AssetLocation", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="StaffRoomAllocation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "room", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.Room" + ), + ), + ( + "staff", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="ShiftingRequestComment", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("comment", models.TextField(blank=True, default="")), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "request", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.ShiftingRequest", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="ResourceRequestComment", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("comment", models.TextField(blank=True, default="")), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "request", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.ResourceRequest", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PrescriptionSupplier", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "scheme", + models.IntegerField( + choices=[ + (10, "GOVERNMENT_SUPPLY"), + (30, "DONATION"), + (40, "PAID_BY_PATIENT"), + ], + default=10, + ), + ), + ( + "status", + models.IntegerField( + choices=[ + (10, "PENDING"), + (30, "INITIATED"), + (40, "COMPLETED"), + (50, "DEFERRED"), + ], + default=10, + ), + ), + ("supplier", models.TextField(blank=True, default="")), + ("remarks", models.TextField(blank=True, default="")), + ( + "consultation", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="patient_consultation", + to="facility.PatientConsultation", + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.Facility", + ), + ), + ( + "updated_user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Prescription", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "prescription_type", + models.CharField( + choices=[("DISCHARGE", "DISCHARGE"), ("REGULAR", "REGULAR")], + default="REGULAR", + max_length=100, + ), + ), + ("medicine", models.CharField(max_length=1023)), + ( + "route", + models.CharField( + blank=True, + choices=[ + ("ORAL", "Oral"), + ("IV", "IV"), + ("IM", "IM"), + ("SC", "S/C"), + ], + max_length=100, + null=True, + ), + ), + ("dosage", models.CharField(blank=True, max_length=100, null=True)), + ("is_prn", models.BooleanField(default=False)), + ( + "frequency", + models.CharField( + blank=True, + choices=[ + ("STAT", "Immediately"), + ("OD", "once daily"), + ("HS", "Night only"), + ("BD", "Twice daily"), + ("TID", "8th hourly"), + ("QID", "6th hourly"), + ("Q4H", "4th hourly"), + ("QOD", "Alternate day"), + ("QWK", "Once a week"), + ], + max_length=100, + null=True, + ), + ), + ("days", models.IntegerField(blank=True, null=True)), + ("indicator", models.TextField(blank=True, null=True)), + ("max_dosage", models.CharField(blank=True, max_length=100, null=True)), + ("min_hours_between_doses", models.IntegerField(blank=True, null=True)), + ("notes", models.TextField(blank=True, default="")), + ( + "meta", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict + ), + ), + ("discontinued", models.BooleanField(default=False)), + ("discontinued_reason", models.TextField(blank=True, default="")), + ("discontinued_date", models.DateTimeField(blank=True, null=True)), + ("is_migrated", models.BooleanField(default=False)), + ( + "consultation", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientConsultation", + ), + ), + ( + "prescribed_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientTeleConsultation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "symptoms", + multiselectfield.db.fields.MultiSelectField( + choices=[ + (1, "ASYMPTOMATIC"), + (2, "FEVER"), + (3, "SORE THROAT"), + (4, "COUGH"), + (5, "BREATHLESSNESS"), + (6, "MYALGIA"), + (7, "ABDOMINAL DISCOMFORT"), + (8, "VOMITING"), + (9, "OTHERS"), + (11, "SPUTUM"), + (12, "NAUSEA"), + (13, "CHEST PAIN"), + (14, "HEMOPTYSIS"), + (15, "NASAL DISCHARGE"), + (16, "BODY ACHE"), + (17, "DIARRHOEA"), + (18, "PAIN"), + (19, "PEDAL EDEMA"), + (20, "WOUND"), + (21, "CONSTIPATION"), + (22, "HEAD ACHE"), + (23, "BLEEDING"), + (24, "DIZZINESS"), + ], + max_length=59, + ), + ), + ("other_symptoms", models.TextField(blank=True, null=True)), + ( + "reason", + models.TextField( + blank=True, null=True, verbose_name="Reason for calling" + ), + ), + ("created_date", models.DateTimeField(auto_now_add=True)), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientRegistration", + ), + ), + ], + ), + migrations.CreateModel( + name="PatientSearch", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("patient_id", fernet_fields.fields.EncryptedIntegerField()), + ("name", models.CharField(max_length=120)), + ( + "gender", + models.IntegerField( + choices=[(1, "Male"), (2, "Female"), (3, "Non-binary")] + ), + ), + ("phone_number", models.CharField(max_length=14)), + ("date_of_birth", models.DateField(null=True)), + ("year_of_birth", models.IntegerField()), + ("state_id", models.IntegerField()), + ( + "patient_external_id", + fernet_fields.fields.EncryptedCharField(default="", max_length=100), + ), + ("allow_transfer", models.BooleanField(default=True)), + ("is_active", models.BooleanField(default=True)), + ( + "facility", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.Facility", + ), + ), + ], + ), + migrations.CreateModel( + name="PatientSampleFlow", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "status", + models.IntegerField( + choices=[ + (1, "REQUEST_SUBMITTED"), + (2, "APPROVED"), + (3, "DENIED"), + (4, "SENT_TO_COLLECTON_CENTRE"), + (5, "RECEIVED_AND_FORWARED"), + (6, "RECEIVED_AT_LAB"), + (7, "COMPLETED"), + ] + ), + ), + ("notes", models.CharField(max_length=255)), + ( + "created_by", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "patient_sample", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientSample", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientNotes", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("note", models.TextField(blank=True, default="")), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.Facility", + ), + ), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientRegistration", + ), + ), + ], + options={ + "abstract": False, + }, + bases=( + models.Model, + care.facility.models.mixins.permissions.patient.PatientRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="PatientInvestigation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=500)), + ("unit", models.TextField(blank=True, null=True)), + ("ideal_value", models.TextField(blank=True, null=True)), + ("min_value", models.FloatField(blank=True, default=None, null=True)), + ("max_value", models.FloatField(blank=True, default=None, null=True)), + ( + "investigation_type", + models.CharField( + choices=[ + ("Float", "Float"), + ("String", "String"), + ("Choice", "Choice"), + ], + default=None, + max_length=10, + null=True, + ), + ), + ("choices", models.TextField(blank=True, null=True)), + ( + "groups", + models.ManyToManyField(to="facility.PatientInvestigationGroup"), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientExternalTest", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("srf_id", models.CharField(max_length=255)), + ("name", models.CharField(max_length=1000)), + ("age", models.IntegerField()), + ("age_in", models.CharField(max_length=20)), + ("gender", models.CharField(max_length=10)), + ("address", models.TextField()), + ("mobile_number", models.CharField(max_length=15)), + ("is_repeat", models.BooleanField()), + ("patient_status", models.CharField(max_length=15)), + ("source", models.CharField(blank=True, max_length=255, null=True)), + ( + "patient_category", + models.CharField(blank=True, max_length=255, null=True), + ), + ("lab_name", models.CharField(max_length=255)), + ("test_type", models.CharField(max_length=255)), + ("sample_type", models.CharField(max_length=255)), + ("result", models.CharField(max_length=255)), + ("sample_collection_date", models.DateField(blank=True, null=True)), + ("result_date", models.DateField(blank=True, null=True)), + ("patient_created", models.BooleanField(default=False)), + ( + "district", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="users.District" + ), + ), + ( + "local_body", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="users.LocalBody", + ), + ), + ( + "ward", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.Ward", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientContactDetails", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "relation_with_patient", + models.IntegerField( + choices=[ + (1, "FAMILY_MEMBER"), + (2, "FRIEND"), + (3, "RELATIVE"), + (4, "NEIGHBOUR"), + (5, "TRAVEL_TOGETHER"), + (6, "WHILE_AT_HOSPITAL"), + (7, "WHILE_AT_SHOP"), + (8, "WHILE_AT_OFFICE_OR_ESTABLISHMENT"), + (9, "WORSHIP_PLACE"), + (10, "OTHERS"), + ] + ), + ), + ( + "mode_of_contact", + models.IntegerField( + choices=[ + (1, "TOUCHED_BODY_FLUIDS"), + (2, "DIRECT_PHYSICAL_CONTACT"), + (3, "CLEANED_USED_ITEMS"), + (4, "LIVE_IN_SAME_HOUSEHOLD"), + (5, "CLOSE_CONTACT_WITHOUT_PRECAUTION"), + (6, "CO_PASSENGER_AEROPLANE"), + (7, "HEALTH_CARE_WITH_PPE"), + (8, "SHARED_SAME_SPACE_WITHOUT_HIGH_EXPOSURE"), + (9, "TRAVELLED_TOGETHER_WITHOUT_HIGH_EXPOSURE"), + ] + ), + ), + ("date_of_first_contact", models.DateField(null=True)), + ("date_of_last_contact", models.DateField(null=True)), + ( + "is_primary", + models.BooleanField(help_text="If false, then secondary contact"), + ), + ( + "condition_of_contact_is_symptomatic", + models.BooleanField( + help_text="While in contact, did the patient showing symptoms" + ), + ), + ("deleted", models.BooleanField(default=False)), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="contacted_patients", + to="facility.PatientRegistration", + ), + ), + ( + "patient_in_contact", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="contacts", + to="facility.PatientRegistration", + ), + ), + ], + ), + migrations.AddField( + model_name="patientconsultation", + name="patient", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="consultations", + to="facility.PatientRegistration", + ), + ), + migrations.AddField( + model_name="patientconsultation", + name="referred_to", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="referred_patients", + to="facility.Facility", + ), + ), + migrations.CreateModel( + name="Notification", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "medium_sent", + models.IntegerField( + choices=[(0, "SYSTEM"), (100, "SMS"), (200, "WHATSAPP")], + default=0, + ), + ), + ("read_at", models.DateTimeField(blank=True, null=True)), + ( + "event_type", + models.IntegerField( + choices=[(50, "SYSTEM_GENERATED"), (100, "CUSTOM_MESSAGE")], + default=50, + ), + ), + ( + "event", + models.IntegerField( + choices=[ + (0, "MESSAGE"), + (20, "PATIENT_CREATED"), + (30, "PATIENT_UPDATED"), + (40, "PATIENT_DELETED"), + (50, "PATIENT_CONSULTATION_CREATED"), + (60, "PATIENT_CONSULTATION_UPDATED"), + (70, "PATIENT_CONSULTATION_DELETED"), + (80, "INVESTIGATION_SESSION_CREATED"), + (90, "INVESTIGATION_UPDATED"), + (100, "PATIENT_FILE_UPLOAD_CREATED"), + (110, "CONSULTATION_FILE_UPLOAD_CREATED"), + (120, "PATIENT_CONSULTATION_UPDATE_CREATED"), + (130, "PATIENT_CONSULTATION_UPDATE_UPDATED"), + (140, "PATIENT_CONSULTATION_ASSIGNMENT"), + (200, "SHIFTING_UPDATED"), + ], + default=0, + ), + ), + ("message", models.TextField(default=None, max_length=2000, null=True)), + ( + "caused_objects", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict, null=True + ), + ), + ( + "caused_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="notification_caused_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "intended_for", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="notification_intended_for", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="MedicineAdministration", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("notes", models.TextField(blank=True, default="")), + ( + "administered_date", + models.DateTimeField(default=django.utils.timezone.now), + ), + ( + "administered_by", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "prescription", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="administrations", + to="facility.Prescription", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="LocalBodyScopedSummary", + fields=[ + ( + "id", + models.UUIDField( + db_index=True, + default=uuid.uuid4, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("created_date", models.DateTimeField(auto_now_add=True, null=True)), + ("modified_date", models.DateTimeField(auto_now=True, null=True)), + ( + "s_type", + models.CharField( + choices=[("PatientSummary", "PatientSummary")], max_length=100 + ), + ), + ( + "data", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict, null=True + ), + ), + ( + "lsg", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="users.LocalBody", + ), + ), + ], + ), + migrations.CreateModel( + name="InvestigationValue", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("value", models.FloatField(blank=True, default=None, null=True)), + ("notes", models.TextField(blank=True, default=None, null=True)), + ( + "consultation", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientConsultation", + ), + ), + ( + "group", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientInvestigationGroup", + ), + ), + ( + "investigation", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientInvestigation", + ), + ), + ( + "session", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.InvestigationSession", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="InventoryLog", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "prev_count", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "new_count", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "inventory", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Inventory", + ), + ), + ( + "updated_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.AddField( + model_name="inventory", + name="item", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.InventoryItem" + ), + ), + migrations.CreateModel( + name="HospitalDoctors", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "area", + models.IntegerField( + choices=[ + (1, "General Medicine"), + (2, "Pulmonology"), + (3, "Critical Care"), + (4, "Paediatrics"), + (5, "Other Speciality"), + ] + ), + ), + ("count", models.IntegerField()), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ], + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="HistoricalPatientRegistration", + fields=[ + ( + "id", + models.IntegerField( + auto_created=True, blank=True, db_index=True, verbose_name="ID" + ), + ), + ("external_id", models.UUIDField(db_index=True, default=uuid.uuid4)), + ( + "created_date", + models.DateTimeField( + blank=True, db_index=True, editable=False, null=True + ), + ), + ( + "modified_date", + models.DateTimeField( + blank=True, db_index=True, editable=False, null=True + ), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "source", + models.IntegerField( + choices=[(10, "CARE"), (20, "COVID_TRACKER"), (30, "STAY")], + default=10, + ), + ), + ("name", models.CharField(default="", max_length=200)), + ("age", models.PositiveIntegerField(blank=True, null=True)), + ( + "gender", + models.IntegerField( + choices=[(1, "Male"), (2, "Female"), (3, "Non-binary")] + ), + ), + ( + "phone_number", + models.CharField( + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ( + "emergency_phone_number", + models.CharField( + default="", + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("address", models.TextField(default="")), + ("permanent_address", models.TextField(default="")), + ("pincode", models.IntegerField(blank=True, default=0, null=True)), + ("date_of_birth", models.DateField(default=None, null=True)), + ("year_of_birth", models.IntegerField(default=0, null=True)), + ( + "nationality", + models.CharField( + default="", + max_length=255, + verbose_name="Nationality of Patient", + ), + ), + ( + "passport_no", + models.CharField( + default="", + max_length=255, + verbose_name="Passport Number of Foreign Patients", + ), + ), + ( + "is_medical_worker", + models.BooleanField( + default=False, verbose_name="Is the Patient a Medical Worker" + ), + ), + ( + "blood_group", + models.CharField( + choices=[ + ("A+", "A+"), + ("A-", "A-"), + ("B+", "B+"), + ("B-", "B-"), + ("AB+", "AB+"), + ("AB-", "AB-"), + ("O+", "O+"), + ("O-", "O-"), + ("UNK", "UNKNOWN"), + ], + max_length=4, + null=True, + verbose_name="Blood Group of Patient", + ), + ), + ( + "contact_with_confirmed_carrier", + models.BooleanField( + default=False, + verbose_name="Confirmed Contact with a Covid19 Carrier", + ), + ), + ( + "contact_with_suspected_carrier", + models.BooleanField( + default=False, + verbose_name="Suspected Contact with a Covid19 Carrier", + ), + ), + ("estimated_contact_date", models.DateTimeField(blank=True, null=True)), + ( + "past_travel", + models.BooleanField( + default=False, + verbose_name="Travelled to Any Foreign Countries in the last 28 Days", + ), + ), + ( + "countries_travelled_old", + models.TextField( + blank=True, + editable=False, + null=True, + verbose_name="Countries Patient has Travelled to", + ), + ), + ( + "countries_travelled", + care.utils.models.jsonfield.JSONField( + blank=True, + null=True, + verbose_name="Countries Patient has Travelled to", + ), + ), + ( + "date_of_return", + models.DateTimeField( + blank=True, + null=True, + verbose_name="Return Date from the Last Country if Travelled", + ), + ), + ( + "allergies", + models.TextField( + blank=True, default="", verbose_name="Patient's Known Allergies" + ), + ), + ( + "present_health", + models.TextField( + blank=True, + default="", + verbose_name="Patient's Current Health Details", + ), + ), + ( + "ongoing_medication", + models.TextField( + blank=True, + default="", + verbose_name="Already pescribed medication if any", + ), + ), + ( + "has_SARI", + models.BooleanField( + default=False, verbose_name="Does the Patient Suffer from SARI" + ), + ), + ( + "is_antenatal", + models.BooleanField( + default=None, + verbose_name="Does the patient require Prenatal Care ?", + ), + ), + ( + "ward_old", + models.CharField( + default="", max_length=255, verbose_name="Ward of Patient" + ), + ), + ( + "is_migrant_worker", + models.BooleanField( + default=False, verbose_name="Is Patient a Migrant Worker" + ), + ), + ( + "disease_status", + models.IntegerField( + blank=True, + choices=[ + (1, "SUSPECTED"), + (2, "POSITIVE"), + (3, "NEGATIVE"), + (4, "RECOVERY"), + (5, "RECOVERED"), + (6, "EXPIRED"), + ], + default=1, + verbose_name="Disease Status", + ), + ), + ( + "number_of_aged_dependents", + models.IntegerField( + blank=True, + default=0, + verbose_name="Number of people aged above 60 living with the patient", + ), + ), + ( + "number_of_chronic_diseased_dependents", + models.IntegerField( + blank=True, + default=0, + verbose_name="Number of people who have chronic diseases living with the patient", + ), + ), + ( + "action", + models.IntegerField( + blank=True, + choices=[ + (10, "NO_ACTION"), + (20, "PENDING"), + (30, "SPECIALIST_REQUIRED"), + (40, "PLAN_FOR_HOME_CARE"), + (50, "FOLLOW_UP_NOT_REQUIRED"), + (60, "COMPLETE"), + (70, "REVIEW"), + (80, "NOT_REACHABLE"), + ], + default=10, + null=True, + ), + ), + ( + "review_time", + models.DateTimeField( + blank=True, null=True, verbose_name="Patient's next review time" + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Not active when discharged, or removed from the watchlist", + ), + ), + ( + "date_of_receipt_of_information", + models.DateTimeField( + blank=True, + null=True, + verbose_name="Patient's information received date", + ), + ), + ( + "test_id", + models.CharField(blank=True, default="", max_length=100, null=True), + ), + ( + "date_of_test", + models.DateTimeField( + blank=True, null=True, verbose_name="Patient's test Date" + ), + ), + ("srf_id", models.CharField(blank=True, default="", max_length=200)), + ( + "test_type", + models.IntegerField( + choices=[ + (10, "UNK"), + (20, "ANTIGEN"), + (30, "RTPCR"), + (40, "CBNAAT"), + (50, "TRUENAT"), + (60, "RTLAMP"), + (70, "POCPCR"), + ], + default=10, + ), + ), + ("allow_transfer", models.BooleanField(default=False)), + ( + "will_donate_blood", + models.BooleanField( + default=None, + null=True, + verbose_name="Is Patient Willing to donate Blood", + ), + ), + ( + "fit_for_blood_donation", + models.BooleanField( + default=None, + null=True, + verbose_name="Is Patient fit for donating Blood", + ), + ), + ( + "village", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Vilalge Name of Patient (IDSP Req)", + ), + ), + ( + "designation_of_health_care_worker", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Designation of Health Care Worker (IDSP Req)", + ), + ), + ( + "instituion_of_health_care_worker", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Institution of Healtcare Worker (IDSP Req)", + ), + ), + ( + "transit_details", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Transit Details (IDSP Req)", + ), + ), + ( + "frontline_worker", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Front Line Worker (IDSP Req)", + ), + ), + ( + "date_of_result", + models.DateTimeField( + blank=True, + default=None, + null=True, + verbose_name="Patient's result Date", + ), + ), + ( + "number_of_primary_contacts", + models.IntegerField( + blank=True, + default=None, + null=True, + verbose_name="Number of Primary Contacts", + ), + ), + ( + "number_of_secondary_contacts", + models.IntegerField( + blank=True, + default=None, + null=True, + verbose_name="Number of Secondary Contacts", + ), + ), + ( + "is_vaccinated", + models.BooleanField( + default=False, + verbose_name="Is the Patient Vaccinated Against COVID-19", + ), + ), + ( + "number_of_doses", + models.PositiveIntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(3), + ], + ), + ), + ( + "vaccine_name", + models.CharField( + choices=[ + ("CoviShield", "COVISHIELD"), + ("Covaxin", "COVAXIN"), + ("Sputnik", "SPUTNIK"), + ("Moderna", "MODERNA"), + ("Pfizer", "PFIZER"), + ("Janssen", "JANSSEN"), + ("Sinovac", "SINOVAC"), + ], + default=None, + max_length=15, + null=True, + ), + ), + ( + "covin_id", + models.CharField( + blank=True, + default=None, + max_length=15, + null=True, + verbose_name="COVID-19 Vaccination ID", + ), + ), + ( + "last_vaccinated_date", + models.DateTimeField( + blank=True, null=True, verbose_name="Date Last Vaccinated" + ), + ), + ( + "cluster_name", + models.CharField( + blank=True, + default=None, + max_length=255, + null=True, + verbose_name="Name/ Cluster of Contact", + ), + ), + ( + "is_declared_positive", + models.BooleanField( + default=None, + null=True, + verbose_name="Is Patient Declared Positive", + ), + ), + ( + "date_declared_positive", + models.DateTimeField( + blank=True, + null=True, + verbose_name="Date Patient is Declared Positive", + ), + ), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField()), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "assigned_to", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "created_by", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "district", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="users.District", + ), + ), + ( + "facility", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="facility.Facility", + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "last_consultation", + models.ForeignKey( + blank=True, + db_constraint=False, + default=None, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="facility.PatientConsultation", + ), + ), + ( + "last_edited", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "local_body", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="users.LocalBody", + ), + ), + ( + "nearest_facility", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="facility.Facility", + ), + ), + ( + "state", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="users.State", + ), + ), + ( + "ward", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="users.Ward", + ), + ), + ], + options={ + "verbose_name": "historical patient registration", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": "history_date", + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="HistoricalFacilityCapacity", + fields=[ + ( + "id", + models.IntegerField( + auto_created=True, blank=True, db_index=True, verbose_name="ID" + ), + ), + ("external_id", models.UUIDField(db_index=True, default=uuid.uuid4)), + ( + "created_date", + models.DateTimeField( + blank=True, db_index=True, editable=False, null=True + ), + ), + ( + "modified_date", + models.DateTimeField( + blank=True, db_index=True, editable=False, null=True + ), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "room_type", + models.IntegerField( + choices=[ + (0, "Total"), + (2, "Hostel"), + (3, "Single Room with Attached Bathroom"), + (40, "KASP Beds"), + (50, "KASP ICU beds"), + (60, "KASP Oxygen beds"), + (70, "KASP Ventilator beds"), + (1, "General Bed"), + (10, "ICU"), + (20, "Ventilator"), + (30, "Covid Beds"), + (100, "Covid Ventilators"), + (110, "Covid ICU"), + (120, "Covid Oxygen beds"), + (150, "Oxygen beds"), + ] + ), + ), + ( + "total_capacity", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "current_capacity", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField()), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "facility", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="facility.Facility", + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "historical facility capacity", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": "history_date", + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="FileUpload", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=2000)), + ("internal_name", models.CharField(max_length=2000)), + ("associating_id", models.CharField(max_length=100)), + ("upload_completed", models.BooleanField(default=False)), + ("is_archived", models.BooleanField(default=False)), + ("archive_reason", models.TextField(blank=True)), + ("archived_datetime", models.DateTimeField(blank=True, null=True)), + ( + "file_type", + models.IntegerField( + choices=[ + (1, "PATIENT"), + (2, "CONSULTATION"), + (3, "SAMPLE_MANAGEMENT"), + (4, "CLAIM"), + (5, "DISCHARGE_SUMMARY"), + ], + default=1, + ), + ), + ( + "file_category", + models.CharField( + choices=[ + ("UNSPECIFIED", "UNSPECIFIED"), + ("XRAY", "XRAY"), + ("AUDIO", "AUDIO"), + ("IDENTITY_PROOF", "IDENTITY_PROOF"), + ], + default="UNSPECIFIED", + max_length=100, + ), + ), + ( + "archived_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="archived_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "uploaded_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="uploaded_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="FacilityVolunteer", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "volunteer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="FacilityUser", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "created_by", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="created_users", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="FacilityStaff", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "staff", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="FacilityRelatedSummary", + fields=[ + ( + "id", + models.UUIDField( + db_index=True, + default=uuid.uuid4, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("created_date", models.DateTimeField(auto_now_add=True, null=True)), + ("modified_date", models.DateTimeField(auto_now=True, null=True)), + ( + "s_type", + models.CharField( + choices=[ + ("FacilityCapacity", "FacilityCapacity"), + ("PatientSummary", "PatientSummary"), + ("TestSummary", "TestSummary"), + ("TriageSummary", "TriageSummary"), + ], + max_length=100, + ), + ), + ( + "data", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict, null=True + ), + ), + ( + "facility", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ], + ), + migrations.CreateModel( + name="FacilityPatientStatsHistory", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("entry_date", models.DateField()), + ("num_patients_visited", models.IntegerField(default=0)), + ("num_patients_home_quarantine", models.IntegerField(default=0)), + ("num_patients_isolation", models.IntegerField(default=0)), + ("num_patient_referred", models.IntegerField(default=0)), + ("num_patient_confirmed_positive", models.IntegerField(default=0)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.Facility", + ), + ), + ], + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="FacilityLocalGovtBody", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "district", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.District", + ), + ), + ( + "facility", + models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.Facility", + ), + ), + ( + "local_body", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.LocalBody", + ), + ), + ], + ), + migrations.CreateModel( + name="FacilityInventoryUnitConverter", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("multiplier", models.FloatField()), + ( + "from_unit", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="from_unit", + to="facility.FacilityInventoryUnit", + ), + ), + ( + "to_unit", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="to_unit", + to="facility.FacilityInventoryUnit", + ), + ), + ], + ), + migrations.CreateModel( + name="FacilityInventorySummary", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("quantity", models.FloatField(default=0)), + ("is_low", models.BooleanField(default=False)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "item", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.FacilityInventoryItem", + ), + ), + ], + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="FacilityInventoryMinQuantity", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("min_quantity", models.FloatField(default=0)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "item", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.FacilityInventoryItem", + ), + ), + ], + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="FacilityInventoryLog", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("current_stock", models.FloatField(default=0)), + ("quantity_in_default_unit", models.FloatField(default=0)), + ("quantity", models.FloatField(default=0)), + ("is_incoming", models.BooleanField()), + ("probable_accident", models.BooleanField(default=False)), + ( + "created_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "item", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.FacilityInventoryItem", + ), + ), + ( + "unit", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.FacilityInventoryUnit", + ), + ), + ], + options={ + "abstract": False, + }, + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.AddField( + model_name="facilityinventoryitem", + name="allowed_units", + field=models.ManyToManyField( + related_name="allowed_units", to="facility.FacilityInventoryUnit" + ), + ), + migrations.AddField( + model_name="facilityinventoryitem", + name="default_unit", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="default_unit", + to="facility.FacilityInventoryUnit", + ), + ), + migrations.AddField( + model_name="facilityinventoryitem", + name="tags", + field=models.ManyToManyField(to="facility.FacilityInventoryItemTag"), + ), + migrations.CreateModel( + name="FacilityInventoryBurnRate", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("burn_rate", models.FloatField(default=0)), + ("current_stock", models.FloatField(default=0)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ( + "item", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="facility.FacilityInventoryItem", + ), + ), + ], + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.CreateModel( + name="FacilityDefaultAssetLocation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.Facility", + ), + ), + ( + "location", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.AssetLocation", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="FacilityCapacity", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "room_type", + models.IntegerField( + choices=[ + (0, "Total"), + (2, "Hostel"), + (3, "Single Room with Attached Bathroom"), + (40, "KASP Beds"), + (50, "KASP ICU beds"), + (60, "KASP Oxygen beds"), + (70, "KASP Ventilator beds"), + (1, "General Bed"), + (10, "ICU"), + (20, "Ventilator"), + (30, "Covid Beds"), + (100, "Covid Ventilators"), + (110, "Covid ICU"), + (120, "Covid Oxygen beds"), + (150, "Oxygen beds"), + ] + ), + ), + ( + "total_capacity", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "current_capacity", + models.IntegerField( + default=0, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + ( + "facility", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Facility", + ), + ), + ], + options={ + "verbose_name_plural": "Facility Capacities", + }, + bases=( + models.Model, + care.facility.models.mixins.permissions.facility.FacilityRelatedPermissionMixin, + ), + ), + migrations.AddField( + model_name="facility", + name="users", + field=models.ManyToManyField( + related_name="facilities", + through="facility.FacilityUser", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="facility", + name="ward", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="users.Ward", + ), + ), + migrations.CreateModel( + name="DistrictScopedSummary", + fields=[ + ( + "id", + models.UUIDField( + db_index=True, + default=uuid.uuid4, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("created_date", models.DateTimeField(auto_now_add=True, null=True)), + ("modified_date", models.DateTimeField(auto_now=True, null=True)), + ( + "s_type", + models.CharField( + choices=[("PatientSummary", "PatientSummary")], max_length=100 + ), + ), + ( + "data", + django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default=dict, null=True + ), + ), + ( + "district", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="users.District", + ), + ), + ], + ), + migrations.CreateModel( + name="Disease", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "disease", + models.IntegerField( + choices=[ + (1, "NO"), + (2, "Diabetes"), + (3, "Heart Disease"), + (4, "HyperTension"), + (5, "Kidney Diseases"), + (6, "Lung Diseases/Asthma"), + (7, "Cancer"), + (8, "OTHER"), + ] + ), + ), + ("details", models.TextField(blank=True, null=True)), + ("deleted", models.BooleanField(default=False)), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="medical_history", + to="facility.PatientRegistration", + ), + ), + ], + ), + migrations.AddField( + model_name="dailyround", + name="consultation", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="daily_rounds", + to="facility.PatientConsultation", + ), + ), + migrations.AddField( + model_name="dailyround", + name="created_by", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="update_created_user", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="dailyround", + name="last_edited_by", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="update_last_edited_user", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="consultationbed", + name="consultation", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="facility.PatientConsultation", + ), + ), + migrations.AddField( + model_name="building", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="facility.Facility" + ), + ), + migrations.AddField( + model_name="bed", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.Facility" + ), + ), + migrations.AddField( + model_name="bed", + name="location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.AssetLocation" + ), + ), + migrations.CreateModel( + name="AssetTransaction", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "asset", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.Asset" + ), + ), + ( + "from_location", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="from_location", + to="facility.AssetLocation", + ), + ), + ( + "performed_by", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "to_location", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="to_location", + to="facility.AssetLocation", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.AddField( + model_name="assetlocation", + name="facility", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.Facility" + ), + ), + migrations.AddField( + model_name="assetbed", + name="bed", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.Bed" + ), + ), + migrations.AddField( + model_name="asset", + name="current_location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="facility.AssetLocation" + ), + ), + migrations.CreateModel( + name="AmbulanceDriver", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=255)), + ( + "phone_number", + models.CharField( + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ("is_smart_phone", models.BooleanField()), + ( + "ambulance", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.Ambulance", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="PatientConsultationICMR", + fields=[], + options={ + "proxy": True, + "indexes": [], + "constraints": [], + }, + bases=("facility.patientconsultation",), + ), + migrations.CreateModel( + name="PatientIcmr", + fields=[], + options={ + "proxy": True, + "indexes": [], + "constraints": [], + }, + bases=("facility.patientregistration",), + ), + migrations.CreateModel( + name="PatientSampleICMR", + fields=[], + options={ + "proxy": True, + "indexes": [], + "constraints": [], + }, + bases=("facility.patientsample",), + ), + migrations.AddIndex( + model_name="shiftingrequest", + index=models.Index( + fields=["status", "deleted"], name="facility_sh_status_2f7458_idx" + ), + ), + migrations.AddIndex( + model_name="resourcerequest", + index=models.Index( + fields=["status", "deleted"], name="facility_re_status_52e9a4_idx" + ), + ), + migrations.AddIndex( + model_name="patientsearch", + index=models.Index( + fields=["year_of_birth", "date_of_birth", "phone_number"], + name="facility_pa_year_of_cf9f3e_idx", + ), + ), + migrations.AddIndex( + model_name="patientsearch", + index=models.Index( + fields=["year_of_birth", "phone_number"], + name="facility_pa_year_of_c04a3d_idx", + ), + ), + migrations.AddConstraint( + model_name="patientconsultation", + constraint=models.CheckConstraint( + check=models.Q( + models.Q(_negated=True, suggestion="R"), + ("referred_to__isnull", False), + ("referred_to_external__isnull", False), + _connector="OR", + ), + name="if_referral_suggested", + ), + ), + migrations.AddConstraint( + model_name="patientconsultation", + constraint=models.CheckConstraint( + check=models.Q( + ("admitted", False), + ("admission_date__isnull", False), + _connector="OR", + ), + name="if_admitted", + ), + ), + migrations.AddIndex( + model_name="localbodyscopedsummary", + index=models.Index( + fields=["-modified_date"], name="facility_lo_modifie_a60b84_idx" + ), + ), + migrations.AddIndex( + model_name="localbodyscopedsummary", + index=models.Index( + fields=["-created_date"], name="facility_lo_created_0e69e8_idx" + ), + ), + migrations.AddIndex( + model_name="localbodyscopedsummary", + index=models.Index(fields=["s_type"], name="facility_lo_s_type_f5b38c_idx"), + ), + migrations.AddIndex( + model_name="localbodyscopedsummary", + index=models.Index( + fields=["-created_date", "s_type"], + name="facility_lo_created_d5c5c0_idx", + ), + ), + migrations.AddIndex( + model_name="investigationsession", + index=models.Index( + fields=["-created_date"], name="facility_in_created_ea2255_idx" + ), + ), + migrations.AddIndex( + model_name="hospitaldoctors", + index=partial_index.PartialIndex( + fields=["facility", "area"], + name="facility_ho_facilit_ec08f4_partial", + unique=True, + where=partial_index.PQ(deleted=False), + ), + ), + migrations.AlterUniqueTogether( + name="facilityuser", + unique_together={("facility", "user")}, + ), + migrations.AddIndex( + model_name="facilityrelatedsummary", + index=models.Index( + fields=["-modified_date"], name="facility_fa_modifie_552c15_idx" + ), + ), + migrations.AddIndex( + model_name="facilityrelatedsummary", + index=models.Index( + fields=["-created_date"], name="facility_fa_created_adc5be_idx" + ), + ), + migrations.AddIndex( + model_name="facilityrelatedsummary", + index=models.Index(fields=["s_type"], name="facility_fa_s_type_7b0ae3_idx"), + ), + migrations.AddIndex( + model_name="facilityrelatedsummary", + index=models.Index( + fields=["-created_date", "s_type"], + name="facility_fa_created_81979e_idx", + ), + ), + migrations.AlterUniqueTogether( + name="facilitypatientstatshistory", + unique_together={("facility", "entry_date")}, + ), + migrations.AddConstraint( + model_name="facilitylocalgovtbody", + constraint=models.CheckConstraint( + check=models.Q( + ("local_body__isnull", False), + ("district__isnull", False), + _connector="OR", + ), + name="cons_facilitylocalgovtbody_only_one_null", + ), + ), + migrations.AddIndex( + model_name="facilityinventorysummary", + index=partial_index.PartialIndex( + fields=["facility", "item"], + name="facility_fa_facilit_ff33b8_partial", + unique=True, + where=partial_index.PQ(deleted=False), + ), + ), + migrations.AddIndex( + model_name="facilityinventoryminquantity", + index=partial_index.PartialIndex( + fields=["facility", "item"], + name="facility_fa_facilit_a9eb9a_partial", + unique=True, + where=partial_index.PQ(deleted=False), + ), + ), + migrations.AddIndex( + model_name="facilityinventoryburnrate", + index=models.Index( + fields=["facility", "item"], name="facility_fa_facilit_e2046a_idx" + ), + ), + migrations.AlterUniqueTogether( + name="facilityinventoryburnrate", + unique_together={("facility", "item")}, + ), + migrations.AddIndex( + model_name="facilitycapacity", + index=partial_index.PartialIndex( + fields=["facility", "room_type"], + name="facility_fa_facilit_ec2b0e_partial", + unique=True, + where=partial_index.PQ(deleted=False), + ), + ), + migrations.AddIndex( + model_name="districtscopedsummary", + index=models.Index( + fields=["-modified_date"], name="facility_di_modifie_09d187_idx" + ), + ), + migrations.AddIndex( + model_name="districtscopedsummary", + index=models.Index( + fields=["-created_date"], name="facility_di_created_74064b_idx" + ), + ), + migrations.AddIndex( + model_name="districtscopedsummary", + index=models.Index(fields=["s_type"], name="facility_di_s_type_7410ec_idx"), + ), + migrations.AddIndex( + model_name="districtscopedsummary", + index=models.Index( + fields=["-created_date", "s_type"], + name="facility_di_created_45003b_idx", + ), + ), + migrations.AddIndex( + model_name="disease", + index=partial_index.PartialIndex( + fields=["patient", "disease"], + name="facility_di_patient_640ef7_partial", + unique=True, + where=partial_index.PQ(deleted=False), + ), + ), + migrations.AddConstraint( + model_name="asset", + constraint=models.UniqueConstraint( + condition=models.Q(qr_code_id__isnull=False), + fields=("qr_code_id",), + name="qr_code_unique_when_not_null", + ), + ), + ] diff --git a/care/facility/migrations/0001_initial.py b/care/facility/migrations_old/0001_initial.py similarity index 100% rename from care/facility/migrations/0001_initial.py rename to care/facility/migrations_old/0001_initial.py diff --git a/care/facility/migrations/0002_auto_20200319_1244.py b/care/facility/migrations_old/0002_auto_20200319_1244.py similarity index 100% rename from care/facility/migrations/0002_auto_20200319_1244.py rename to care/facility/migrations_old/0002_auto_20200319_1244.py diff --git a/care/facility/migrations/0003_auto_20200319_1739.py b/care/facility/migrations_old/0003_auto_20200319_1739.py similarity index 100% rename from care/facility/migrations/0003_auto_20200319_1739.py rename to care/facility/migrations_old/0003_auto_20200319_1739.py diff --git a/care/facility/migrations/0004_auto_20200319_1833.py b/care/facility/migrations_old/0004_auto_20200319_1833.py similarity index 100% rename from care/facility/migrations/0004_auto_20200319_1833.py rename to care/facility/migrations_old/0004_auto_20200319_1833.py diff --git a/care/facility/migrations/0005_facility_created_by.py b/care/facility/migrations_old/0005_facility_created_by.py similarity index 100% rename from care/facility/migrations/0005_facility_created_by.py rename to care/facility/migrations_old/0005_facility_created_by.py diff --git a/care/facility/migrations/0006_auto_20200320_1616.py b/care/facility/migrations_old/0006_auto_20200320_1616.py similarity index 100% rename from care/facility/migrations/0006_auto_20200320_1616.py rename to care/facility/migrations_old/0006_auto_20200320_1616.py diff --git a/care/facility/migrations/0007_auto_20200320_1641.py b/care/facility/migrations_old/0007_auto_20200320_1641.py similarity index 100% rename from care/facility/migrations/0007_auto_20200320_1641.py rename to care/facility/migrations_old/0007_auto_20200320_1641.py diff --git a/care/facility/migrations/0008_auto_20200320_1847.py b/care/facility/migrations_old/0008_auto_20200320_1847.py similarity index 100% rename from care/facility/migrations/0008_auto_20200320_1847.py rename to care/facility/migrations_old/0008_auto_20200320_1847.py diff --git a/care/facility/migrations/0009_auto_20200320_1850.py b/care/facility/migrations_old/0009_auto_20200320_1850.py similarity index 100% rename from care/facility/migrations/0009_auto_20200320_1850.py rename to care/facility/migrations_old/0009_auto_20200320_1850.py diff --git a/care/facility/migrations/0010_auto_20200321_0758.py b/care/facility/migrations_old/0010_auto_20200321_0758.py similarity index 100% rename from care/facility/migrations/0010_auto_20200321_0758.py rename to care/facility/migrations_old/0010_auto_20200321_0758.py diff --git a/care/facility/migrations/0011_auto_20200321_0927.py b/care/facility/migrations_old/0011_auto_20200321_0927.py similarity index 100% rename from care/facility/migrations/0011_auto_20200321_0927.py rename to care/facility/migrations_old/0011_auto_20200321_0927.py diff --git a/care/facility/migrations/0011_facility_phone_number.py b/care/facility/migrations_old/0011_facility_phone_number.py similarity index 100% rename from care/facility/migrations/0011_facility_phone_number.py rename to care/facility/migrations_old/0011_facility_phone_number.py diff --git a/care/facility/migrations/0012_merge_20200321_1015.py b/care/facility/migrations_old/0012_merge_20200321_1015.py similarity index 100% rename from care/facility/migrations/0012_merge_20200321_1015.py rename to care/facility/migrations_old/0012_merge_20200321_1015.py diff --git a/care/facility/migrations/0013_auto_20200322_1158.py b/care/facility/migrations_old/0013_auto_20200322_1158.py similarity index 100% rename from care/facility/migrations/0013_auto_20200322_1158.py rename to care/facility/migrations_old/0013_auto_20200322_1158.py diff --git a/care/facility/migrations/0014_delete_facilitylocation.py b/care/facility/migrations_old/0014_delete_facilitylocation.py similarity index 100% rename from care/facility/migrations/0014_delete_facilitylocation.py rename to care/facility/migrations_old/0014_delete_facilitylocation.py diff --git a/care/facility/migrations/0014_facility_oxygen_capacity.py b/care/facility/migrations_old/0014_facility_oxygen_capacity.py similarity index 100% rename from care/facility/migrations/0014_facility_oxygen_capacity.py rename to care/facility/migrations_old/0014_facility_oxygen_capacity.py diff --git a/care/facility/migrations/0015_facility_location.py b/care/facility/migrations_old/0015_facility_location.py similarity index 100% rename from care/facility/migrations/0015_facility_location.py rename to care/facility/migrations_old/0015_facility_location.py diff --git a/care/facility/migrations/0016_merge_20200322_1622.py b/care/facility/migrations_old/0016_merge_20200322_1622.py similarity index 100% rename from care/facility/migrations/0016_merge_20200322_1622.py rename to care/facility/migrations_old/0016_merge_20200322_1622.py diff --git a/care/facility/migrations/0017_auto_20200322_1642.py b/care/facility/migrations_old/0017_auto_20200322_1642.py similarity index 100% rename from care/facility/migrations/0017_auto_20200322_1642.py rename to care/facility/migrations_old/0017_auto_20200322_1642.py diff --git a/care/facility/migrations/0018_ambulance_ambulancedriver.py b/care/facility/migrations_old/0018_ambulance_ambulancedriver.py similarity index 100% rename from care/facility/migrations/0018_ambulance_ambulancedriver.py rename to care/facility/migrations_old/0018_ambulance_ambulancedriver.py diff --git a/care/facility/migrations/0019_auto_20200322_2056.py b/care/facility/migrations_old/0019_auto_20200322_2056.py similarity index 100% rename from care/facility/migrations/0019_auto_20200322_2056.py rename to care/facility/migrations_old/0019_auto_20200322_2056.py diff --git a/care/facility/migrations/0020_auto_20200323_1029.py b/care/facility/migrations_old/0020_auto_20200323_1029.py similarity index 100% rename from care/facility/migrations/0020_auto_20200323_1029.py rename to care/facility/migrations_old/0020_auto_20200323_1029.py diff --git a/care/facility/migrations/0021_auto_20200324_0756.py b/care/facility/migrations_old/0021_auto_20200324_0756.py similarity index 100% rename from care/facility/migrations/0021_auto_20200324_0756.py rename to care/facility/migrations_old/0021_auto_20200324_0756.py diff --git a/care/facility/migrations/0022_ambulance_ambulance_type.py b/care/facility/migrations_old/0022_ambulance_ambulance_type.py similarity index 100% rename from care/facility/migrations/0022_ambulance_ambulance_type.py rename to care/facility/migrations_old/0022_ambulance_ambulance_type.py diff --git a/care/facility/migrations/0022_patientregistration_patientteleconsultation.py b/care/facility/migrations_old/0022_patientregistration_patientteleconsultation.py similarity index 100% rename from care/facility/migrations/0022_patientregistration_patientteleconsultation.py rename to care/facility/migrations_old/0022_patientregistration_patientteleconsultation.py diff --git a/care/facility/migrations/0023_merge_20200324_1959.py b/care/facility/migrations_old/0023_merge_20200324_1959.py similarity index 100% rename from care/facility/migrations/0023_merge_20200324_1959.py rename to care/facility/migrations_old/0023_merge_20200324_1959.py diff --git a/care/facility/migrations/0024_auto_20200325_0311.py b/care/facility/migrations_old/0024_auto_20200325_0311.py similarity index 100% rename from care/facility/migrations/0024_auto_20200325_0311.py rename to care/facility/migrations_old/0024_auto_20200325_0311.py diff --git a/care/facility/migrations/0025_auto_20200325_1908.py b/care/facility/migrations_old/0025_auto_20200325_1908.py similarity index 100% rename from care/facility/migrations/0025_auto_20200325_1908.py rename to care/facility/migrations_old/0025_auto_20200325_1908.py diff --git a/care/facility/migrations/0026_map_to_district.py b/care/facility/migrations_old/0026_map_to_district.py similarity index 100% rename from care/facility/migrations/0026_map_to_district.py rename to care/facility/migrations_old/0026_map_to_district.py diff --git a/care/facility/migrations/0027_auto_20200326_1015.py b/care/facility/migrations_old/0027_auto_20200326_1015.py similarity index 100% rename from care/facility/migrations/0027_auto_20200326_1015.py rename to care/facility/migrations_old/0027_auto_20200326_1015.py diff --git a/care/facility/migrations/0028_auto_20200326_1705.py b/care/facility/migrations_old/0028_auto_20200326_1705.py similarity index 100% rename from care/facility/migrations/0028_auto_20200326_1705.py rename to care/facility/migrations_old/0028_auto_20200326_1705.py diff --git a/care/facility/migrations/0028_auto_20200326_1752.py b/care/facility/migrations_old/0028_auto_20200326_1752.py similarity index 100% rename from care/facility/migrations/0028_auto_20200326_1752.py rename to care/facility/migrations_old/0028_auto_20200326_1752.py diff --git a/care/facility/migrations/0029_auto_20200326_1706.py b/care/facility/migrations_old/0029_auto_20200326_1706.py similarity index 100% rename from care/facility/migrations/0029_auto_20200326_1706.py rename to care/facility/migrations_old/0029_auto_20200326_1706.py diff --git a/care/facility/migrations/0030_auto_20200327_0619.py b/care/facility/migrations_old/0030_auto_20200327_0619.py similarity index 100% rename from care/facility/migrations/0030_auto_20200327_0619.py rename to care/facility/migrations_old/0030_auto_20200327_0619.py diff --git a/care/facility/migrations/0030_merge_20200326_2047.py b/care/facility/migrations_old/0030_merge_20200326_2047.py similarity index 100% rename from care/facility/migrations/0030_merge_20200326_2047.py rename to care/facility/migrations_old/0030_merge_20200326_2047.py diff --git a/care/facility/migrations/0031_rename_kasargode.py b/care/facility/migrations_old/0031_rename_kasargode.py similarity index 100% rename from care/facility/migrations/0031_rename_kasargode.py rename to care/facility/migrations_old/0031_rename_kasargode.py diff --git a/care/facility/migrations/0032_merge_20200327_1215.py b/care/facility/migrations_old/0032_merge_20200327_1215.py similarity index 100% rename from care/facility/migrations/0032_merge_20200327_1215.py rename to care/facility/migrations_old/0032_merge_20200327_1215.py diff --git a/care/facility/migrations/0033_ambulance_service_charge.py b/care/facility/migrations_old/0033_ambulance_service_charge.py similarity index 100% rename from care/facility/migrations/0033_ambulance_service_charge.py rename to care/facility/migrations_old/0033_ambulance_service_charge.py diff --git a/care/facility/migrations/0034_auto_20200327_1628.py b/care/facility/migrations_old/0034_auto_20200327_1628.py similarity index 100% rename from care/facility/migrations/0034_auto_20200327_1628.py rename to care/facility/migrations_old/0034_auto_20200327_1628.py diff --git a/care/facility/migrations/0034_facilitypatientstatshistory.py b/care/facility/migrations_old/0034_facilitypatientstatshistory.py similarity index 100% rename from care/facility/migrations/0034_facilitypatientstatshistory.py rename to care/facility/migrations_old/0034_facilitypatientstatshistory.py diff --git a/care/facility/migrations/0035_auto_20200328_0442.py b/care/facility/migrations_old/0035_auto_20200328_0442.py similarity index 100% rename from care/facility/migrations/0035_auto_20200328_0442.py rename to care/facility/migrations_old/0035_auto_20200328_0442.py diff --git a/care/facility/migrations/0035_building_num_buildings.py b/care/facility/migrations_old/0035_building_num_buildings.py similarity index 100% rename from care/facility/migrations/0035_building_num_buildings.py rename to care/facility/migrations_old/0035_building_num_buildings.py diff --git a/care/facility/migrations/0035_historicalfacilitycapacity.py b/care/facility/migrations_old/0035_historicalfacilitycapacity.py similarity index 100% rename from care/facility/migrations/0035_historicalfacilitycapacity.py rename to care/facility/migrations_old/0035_historicalfacilitycapacity.py diff --git a/care/facility/migrations/0036_patientconsultation_created_by.py b/care/facility/migrations_old/0036_patientconsultation_created_by.py similarity index 100% rename from care/facility/migrations/0036_patientconsultation_created_by.py rename to care/facility/migrations_old/0036_patientconsultation_created_by.py diff --git a/care/facility/migrations/0037_auto_20200328_1256.py b/care/facility/migrations_old/0037_auto_20200328_1256.py similarity index 100% rename from care/facility/migrations/0037_auto_20200328_1256.py rename to care/facility/migrations_old/0037_auto_20200328_1256.py diff --git a/care/facility/migrations/0038_merge_20200328_1433.py b/care/facility/migrations_old/0038_merge_20200328_1433.py similarity index 100% rename from care/facility/migrations/0038_merge_20200328_1433.py rename to care/facility/migrations_old/0038_merge_20200328_1433.py diff --git a/care/facility/migrations/0039_auto_20200328_1657.py b/care/facility/migrations_old/0039_auto_20200328_1657.py similarity index 100% rename from care/facility/migrations/0039_auto_20200328_1657.py rename to care/facility/migrations_old/0039_auto_20200328_1657.py diff --git a/care/facility/migrations/0039_auto_20200328_1706.py b/care/facility/migrations_old/0039_auto_20200328_1706.py similarity index 100% rename from care/facility/migrations/0039_auto_20200328_1706.py rename to care/facility/migrations_old/0039_auto_20200328_1706.py diff --git a/care/facility/migrations/0040_auto_20200328_1713.py b/care/facility/migrations_old/0040_auto_20200328_1713.py similarity index 100% rename from care/facility/migrations/0040_auto_20200328_1713.py rename to care/facility/migrations_old/0040_auto_20200328_1713.py diff --git a/care/facility/migrations/0041_merge_20200328_1855.py b/care/facility/migrations_old/0041_merge_20200328_1855.py similarity index 100% rename from care/facility/migrations/0041_merge_20200328_1855.py rename to care/facility/migrations_old/0041_merge_20200328_1855.py diff --git a/care/facility/migrations/0042_auto_20200328_2018.py b/care/facility/migrations_old/0042_auto_20200328_2018.py similarity index 100% rename from care/facility/migrations/0042_auto_20200328_2018.py rename to care/facility/migrations_old/0042_auto_20200328_2018.py diff --git a/care/facility/migrations/0043_populate_facility_district.py b/care/facility/migrations_old/0043_populate_facility_district.py similarity index 100% rename from care/facility/migrations/0043_populate_facility_district.py rename to care/facility/migrations_old/0043_populate_facility_district.py diff --git a/care/facility/migrations/0044_patientregistration_real_name.py b/care/facility/migrations_old/0044_patientregistration_real_name.py similarity index 100% rename from care/facility/migrations/0044_patientregistration_real_name.py rename to care/facility/migrations_old/0044_patientregistration_real_name.py diff --git a/care/facility/migrations/0044_patientsample_patientsampleflow.py b/care/facility/migrations_old/0044_patientsample_patientsampleflow.py similarity index 100% rename from care/facility/migrations/0044_patientsample_patientsampleflow.py rename to care/facility/migrations_old/0044_patientsample_patientsampleflow.py diff --git a/care/facility/migrations/0045_auto_20200329_0757.py b/care/facility/migrations_old/0045_auto_20200329_0757.py similarity index 100% rename from care/facility/migrations/0045_auto_20200329_0757.py rename to care/facility/migrations_old/0045_auto_20200329_0757.py diff --git a/care/facility/migrations/0046_merge_20200329_0842.py b/care/facility/migrations_old/0046_merge_20200329_0842.py similarity index 100% rename from care/facility/migrations/0046_merge_20200329_0842.py rename to care/facility/migrations_old/0046_merge_20200329_0842.py diff --git a/care/facility/migrations/0047_auto_20200329_1051.py b/care/facility/migrations_old/0047_auto_20200329_1051.py similarity index 100% rename from care/facility/migrations/0047_auto_20200329_1051.py rename to care/facility/migrations_old/0047_auto_20200329_1051.py diff --git a/care/facility/migrations/0048_auto_20200330_0433.py b/care/facility/migrations_old/0048_auto_20200330_0433.py similarity index 100% rename from care/facility/migrations/0048_auto_20200330_0433.py rename to care/facility/migrations_old/0048_auto_20200330_0433.py diff --git a/care/facility/migrations/0049_auto_20200330_1047.py b/care/facility/migrations_old/0049_auto_20200330_1047.py similarity index 100% rename from care/facility/migrations/0049_auto_20200330_1047.py rename to care/facility/migrations_old/0049_auto_20200330_1047.py diff --git a/care/facility/migrations/0050_dailyround.py b/care/facility/migrations_old/0050_dailyround.py similarity index 100% rename from care/facility/migrations/0050_dailyround.py rename to care/facility/migrations_old/0050_dailyround.py diff --git a/care/facility/migrations/0051_auto_20200330_1257.py b/care/facility/migrations_old/0051_auto_20200330_1257.py similarity index 100% rename from care/facility/migrations/0051_auto_20200330_1257.py rename to care/facility/migrations_old/0051_auto_20200330_1257.py diff --git a/care/facility/migrations/0052_remove_patientconsultation_created_by.py b/care/facility/migrations_old/0052_remove_patientconsultation_created_by.py similarity index 100% rename from care/facility/migrations/0052_remove_patientconsultation_created_by.py rename to care/facility/migrations_old/0052_remove_patientconsultation_created_by.py diff --git a/care/facility/migrations/0053_delete_duplicate_diseases.py b/care/facility/migrations_old/0053_delete_duplicate_diseases.py similarity index 100% rename from care/facility/migrations/0053_delete_duplicate_diseases.py rename to care/facility/migrations_old/0053_delete_duplicate_diseases.py diff --git a/care/facility/migrations/0054_auto_20200331_0950.py b/care/facility/migrations_old/0054_auto_20200331_0950.py similarity index 100% rename from care/facility/migrations/0054_auto_20200331_0950.py rename to care/facility/migrations_old/0054_auto_20200331_0950.py diff --git a/care/facility/migrations/0055_auto_20200331_1144.py b/care/facility/migrations_old/0055_auto_20200331_1144.py similarity index 100% rename from care/facility/migrations/0055_auto_20200331_1144.py rename to care/facility/migrations_old/0055_auto_20200331_1144.py diff --git a/care/facility/migrations/0056_auto_20200401_0932.py b/care/facility/migrations_old/0056_auto_20200401_0932.py similarity index 100% rename from care/facility/migrations/0056_auto_20200401_0932.py rename to care/facility/migrations_old/0056_auto_20200401_0932.py diff --git a/care/facility/migrations/0057_auto_20200401_1018.py b/care/facility/migrations_old/0057_auto_20200401_1018.py similarity index 100% rename from care/facility/migrations/0057_auto_20200401_1018.py rename to care/facility/migrations_old/0057_auto_20200401_1018.py diff --git a/care/facility/migrations/0058_auto_20200401_1820.py b/care/facility/migrations_old/0058_auto_20200401_1820.py similarity index 100% rename from care/facility/migrations/0058_auto_20200401_1820.py rename to care/facility/migrations_old/0058_auto_20200401_1820.py diff --git a/care/facility/migrations/0059_patientsample_fast_track.py b/care/facility/migrations_old/0059_patientsample_fast_track.py similarity index 100% rename from care/facility/migrations/0059_patientsample_fast_track.py rename to care/facility/migrations_old/0059_patientsample_fast_track.py diff --git a/care/facility/migrations/0060_auto_20200402_1126.py b/care/facility/migrations_old/0060_auto_20200402_1126.py similarity index 100% rename from care/facility/migrations/0060_auto_20200402_1126.py rename to care/facility/migrations_old/0060_auto_20200402_1126.py diff --git a/care/facility/migrations/0061_auto_20200402_1128.py b/care/facility/migrations_old/0061_auto_20200402_1128.py similarity index 100% rename from care/facility/migrations/0061_auto_20200402_1128.py rename to care/facility/migrations_old/0061_auto_20200402_1128.py diff --git a/care/facility/migrations/0062_auto_20200402_1336.py b/care/facility/migrations_old/0062_auto_20200402_1336.py similarity index 100% rename from care/facility/migrations/0062_auto_20200402_1336.py rename to care/facility/migrations_old/0062_auto_20200402_1336.py diff --git a/care/facility/migrations/0062_populate_facility_in_patient.py b/care/facility/migrations_old/0062_populate_facility_in_patient.py similarity index 100% rename from care/facility/migrations/0062_populate_facility_in_patient.py rename to care/facility/migrations_old/0062_populate_facility_in_patient.py diff --git a/care/facility/migrations/0063_merge_20200402_1402.py b/care/facility/migrations_old/0063_merge_20200402_1402.py similarity index 100% rename from care/facility/migrations/0063_merge_20200402_1402.py rename to care/facility/migrations_old/0063_merge_20200402_1402.py diff --git a/care/facility/migrations/0064_auto_20200402_1624.py b/care/facility/migrations_old/0064_auto_20200402_1624.py similarity index 100% rename from care/facility/migrations/0064_auto_20200402_1624.py rename to care/facility/migrations_old/0064_auto_20200402_1624.py diff --git a/care/facility/migrations/0065_auto_20200402_1647.py b/care/facility/migrations_old/0065_auto_20200402_1647.py similarity index 100% rename from care/facility/migrations/0065_auto_20200402_1647.py rename to care/facility/migrations_old/0065_auto_20200402_1647.py diff --git a/care/facility/migrations/0066_auto_20200402_1806.py b/care/facility/migrations_old/0066_auto_20200402_1806.py similarity index 100% rename from care/facility/migrations/0066_auto_20200402_1806.py rename to care/facility/migrations_old/0066_auto_20200402_1806.py diff --git a/care/facility/migrations/0067_auto_20200402_1841.py b/care/facility/migrations_old/0067_auto_20200402_1841.py similarity index 100% rename from care/facility/migrations/0067_auto_20200402_1841.py rename to care/facility/migrations_old/0067_auto_20200402_1841.py diff --git a/care/facility/migrations/0068_auto_20200402_2149.py b/care/facility/migrations_old/0068_auto_20200402_2149.py similarity index 100% rename from care/facility/migrations/0068_auto_20200402_2149.py rename to care/facility/migrations_old/0068_auto_20200402_2149.py diff --git a/care/facility/migrations/0068_auto_20200403_1611.py b/care/facility/migrations_old/0068_auto_20200403_1611.py similarity index 100% rename from care/facility/migrations/0068_auto_20200403_1611.py rename to care/facility/migrations_old/0068_auto_20200403_1611.py diff --git a/care/facility/migrations/0069_auto_20200402_2209.py b/care/facility/migrations_old/0069_auto_20200402_2209.py similarity index 100% rename from care/facility/migrations/0069_auto_20200402_2209.py rename to care/facility/migrations_old/0069_auto_20200402_2209.py diff --git a/care/facility/migrations/0070_auto_20200402_2228.py b/care/facility/migrations_old/0070_auto_20200402_2228.py similarity index 100% rename from care/facility/migrations/0070_auto_20200402_2228.py rename to care/facility/migrations_old/0070_auto_20200402_2228.py diff --git a/care/facility/migrations/0071_auto_20200404_1737.py b/care/facility/migrations_old/0071_auto_20200404_1737.py similarity index 100% rename from care/facility/migrations/0071_auto_20200404_1737.py rename to care/facility/migrations_old/0071_auto_20200404_1737.py diff --git a/care/facility/migrations/0072_merge_20200404_2148.py b/care/facility/migrations_old/0072_merge_20200404_2148.py similarity index 100% rename from care/facility/migrations/0072_merge_20200404_2148.py rename to care/facility/migrations_old/0072_merge_20200404_2148.py diff --git a/care/facility/migrations/0073_auto_20200404_2303.py b/care/facility/migrations_old/0073_auto_20200404_2303.py similarity index 100% rename from care/facility/migrations/0073_auto_20200404_2303.py rename to care/facility/migrations_old/0073_auto_20200404_2303.py diff --git a/care/facility/migrations/0074_auto_20200404_2352.py b/care/facility/migrations_old/0074_auto_20200404_2352.py similarity index 100% rename from care/facility/migrations/0074_auto_20200404_2352.py rename to care/facility/migrations_old/0074_auto_20200404_2352.py diff --git a/care/facility/migrations/0075_auto_20200405_1122.py b/care/facility/migrations_old/0075_auto_20200405_1122.py similarity index 100% rename from care/facility/migrations/0075_auto_20200405_1122.py rename to care/facility/migrations_old/0075_auto_20200405_1122.py diff --git a/care/facility/migrations/0076_auto_20200409_0412.py b/care/facility/migrations_old/0076_auto_20200409_0412.py similarity index 100% rename from care/facility/migrations/0076_auto_20200409_0412.py rename to care/facility/migrations_old/0076_auto_20200409_0412.py diff --git a/care/facility/migrations/0077_auto_20200409_0422.py b/care/facility/migrations_old/0077_auto_20200409_0422.py similarity index 100% rename from care/facility/migrations/0077_auto_20200409_0422.py rename to care/facility/migrations_old/0077_auto_20200409_0422.py diff --git a/care/facility/migrations/0078_auto_20200409_0436.py b/care/facility/migrations_old/0078_auto_20200409_0436.py similarity index 100% rename from care/facility/migrations/0078_auto_20200409_0436.py rename to care/facility/migrations_old/0078_auto_20200409_0436.py diff --git a/care/facility/migrations/0079_auto_20200409_0451.py b/care/facility/migrations_old/0079_auto_20200409_0451.py similarity index 100% rename from care/facility/migrations/0079_auto_20200409_0451.py rename to care/facility/migrations_old/0079_auto_20200409_0451.py diff --git a/care/facility/migrations/0080_auto_20200409_0459.py b/care/facility/migrations_old/0080_auto_20200409_0459.py similarity index 100% rename from care/facility/migrations/0080_auto_20200409_0459.py rename to care/facility/migrations_old/0080_auto_20200409_0459.py diff --git a/care/facility/migrations/0081_auto_20200409_1201.py b/care/facility/migrations_old/0081_auto_20200409_1201.py similarity index 100% rename from care/facility/migrations/0081_auto_20200409_1201.py rename to care/facility/migrations_old/0081_auto_20200409_1201.py diff --git a/care/facility/migrations/0082_populate_patient_search.py b/care/facility/migrations_old/0082_populate_patient_search.py similarity index 100% rename from care/facility/migrations/0082_populate_patient_search.py rename to care/facility/migrations_old/0082_populate_patient_search.py diff --git a/care/facility/migrations/0083_auto_20200411_1136.py b/care/facility/migrations_old/0083_auto_20200411_1136.py similarity index 100% rename from care/facility/migrations/0083_auto_20200411_1136.py rename to care/facility/migrations_old/0083_auto_20200411_1136.py diff --git a/care/facility/migrations/0084_install_trigram_similarity.py b/care/facility/migrations_old/0084_install_trigram_similarity.py similarity index 100% rename from care/facility/migrations/0084_install_trigram_similarity.py rename to care/facility/migrations_old/0084_install_trigram_similarity.py diff --git a/care/facility/migrations/0085_auto_20200412_0116.py b/care/facility/migrations_old/0085_auto_20200412_0116.py similarity index 100% rename from care/facility/migrations/0085_auto_20200412_0116.py rename to care/facility/migrations_old/0085_auto_20200412_0116.py diff --git a/care/facility/migrations/0086_auto_20200412_1313.py b/care/facility/migrations_old/0086_auto_20200412_1313.py similarity index 100% rename from care/facility/migrations/0086_auto_20200412_1313.py rename to care/facility/migrations_old/0086_auto_20200412_1313.py diff --git a/care/facility/migrations/0087_add_users_to_facility_user.py b/care/facility/migrations_old/0087_add_users_to_facility_user.py similarity index 100% rename from care/facility/migrations/0087_add_users_to_facility_user.py rename to care/facility/migrations_old/0087_add_users_to_facility_user.py diff --git a/care/facility/migrations/0088_patientconsultationicmr_patienticmr_patientsampleicmr.py b/care/facility/migrations_old/0088_patientconsultationicmr_patienticmr_patientsampleicmr.py similarity index 100% rename from care/facility/migrations/0088_patientconsultationicmr_patienticmr_patientsampleicmr.py rename to care/facility/migrations_old/0088_patientconsultationicmr_patienticmr_patientsampleicmr.py diff --git a/care/facility/migrations/0089_auto_20200413_2036.py b/care/facility/migrations_old/0089_auto_20200413_2036.py similarity index 100% rename from care/facility/migrations/0089_auto_20200413_2036.py rename to care/facility/migrations_old/0089_auto_20200413_2036.py diff --git a/care/facility/migrations/0090_auto_20200415_0710.py b/care/facility/migrations_old/0090_auto_20200415_0710.py similarity index 100% rename from care/facility/migrations/0090_auto_20200415_0710.py rename to care/facility/migrations_old/0090_auto_20200415_0710.py diff --git a/care/facility/migrations/0091_auto_20200415_1158.py b/care/facility/migrations_old/0091_auto_20200415_1158.py similarity index 100% rename from care/facility/migrations/0091_auto_20200415_1158.py rename to care/facility/migrations_old/0091_auto_20200415_1158.py diff --git a/care/facility/migrations/0092_recompute_facility_types.py b/care/facility/migrations_old/0092_recompute_facility_types.py similarity index 100% rename from care/facility/migrations/0092_recompute_facility_types.py rename to care/facility/migrations_old/0092_recompute_facility_types.py diff --git a/care/facility/migrations/0093_auto_20200415_1102.py b/care/facility/migrations_old/0093_auto_20200415_1102.py similarity index 100% rename from care/facility/migrations/0093_auto_20200415_1102.py rename to care/facility/migrations_old/0093_auto_20200415_1102.py diff --git a/care/facility/migrations/0094_auto_20200417_1038.py b/care/facility/migrations_old/0094_auto_20200417_1038.py similarity index 100% rename from care/facility/migrations/0094_auto_20200417_1038.py rename to care/facility/migrations_old/0094_auto_20200417_1038.py diff --git a/care/facility/migrations/0095_recompute_facility_types.py b/care/facility/migrations_old/0095_recompute_facility_types.py similarity index 100% rename from care/facility/migrations/0095_recompute_facility_types.py rename to care/facility/migrations_old/0095_recompute_facility_types.py diff --git a/care/facility/migrations/0096_auto_20200416_1414.py b/care/facility/migrations_old/0096_auto_20200416_1414.py similarity index 100% rename from care/facility/migrations/0096_auto_20200416_1414.py rename to care/facility/migrations_old/0096_auto_20200416_1414.py diff --git a/care/facility/migrations/0097_auto_20200417_1404.py b/care/facility/migrations_old/0097_auto_20200417_1404.py similarity index 100% rename from care/facility/migrations/0097_auto_20200417_1404.py rename to care/facility/migrations_old/0097_auto_20200417_1404.py diff --git a/care/facility/migrations/0098_auto_20200418_1302.py b/care/facility/migrations_old/0098_auto_20200418_1302.py similarity index 100% rename from care/facility/migrations/0098_auto_20200418_1302.py rename to care/facility/migrations_old/0098_auto_20200418_1302.py diff --git a/care/facility/migrations/0099_auto_20200418_2030.py b/care/facility/migrations_old/0099_auto_20200418_2030.py similarity index 100% rename from care/facility/migrations/0099_auto_20200418_2030.py rename to care/facility/migrations_old/0099_auto_20200418_2030.py diff --git a/care/facility/migrations/0100_auto_20200418_2315.py b/care/facility/migrations_old/0100_auto_20200418_2315.py similarity index 100% rename from care/facility/migrations/0100_auto_20200418_2315.py rename to care/facility/migrations_old/0100_auto_20200418_2315.py diff --git a/care/facility/migrations/0101_populate_countries_travelled.py b/care/facility/migrations_old/0101_populate_countries_travelled.py similarity index 100% rename from care/facility/migrations/0101_populate_countries_travelled.py rename to care/facility/migrations_old/0101_populate_countries_travelled.py diff --git a/care/facility/migrations/0102_auto_20200424_1508.py b/care/facility/migrations_old/0102_auto_20200424_1508.py similarity index 100% rename from care/facility/migrations/0102_auto_20200424_1508.py rename to care/facility/migrations_old/0102_auto_20200424_1508.py diff --git a/care/facility/migrations/0103_auto_20200425_1440.py b/care/facility/migrations_old/0103_auto_20200425_1440.py similarity index 100% rename from care/facility/migrations/0103_auto_20200425_1440.py rename to care/facility/migrations_old/0103_auto_20200425_1440.py diff --git a/care/facility/migrations/0104_populate_patient_external_ids.py b/care/facility/migrations_old/0104_populate_patient_external_ids.py similarity index 100% rename from care/facility/migrations/0104_populate_patient_external_ids.py rename to care/facility/migrations_old/0104_populate_patient_external_ids.py diff --git a/care/facility/migrations/0105_auto_20200425_1446.py b/care/facility/migrations_old/0105_auto_20200425_1446.py similarity index 100% rename from care/facility/migrations/0105_auto_20200425_1446.py rename to care/facility/migrations_old/0105_auto_20200425_1446.py diff --git a/care/facility/migrations/0106_auto_20200510_1557.py b/care/facility/migrations_old/0106_auto_20200510_1557.py similarity index 100% rename from care/facility/migrations/0106_auto_20200510_1557.py rename to care/facility/migrations_old/0106_auto_20200510_1557.py diff --git a/care/facility/migrations/0107_populate_external_ids.py b/care/facility/migrations_old/0107_populate_external_ids.py similarity index 100% rename from care/facility/migrations/0107_populate_external_ids.py rename to care/facility/migrations_old/0107_populate_external_ids.py diff --git a/care/facility/migrations/0108_auto_20200510_1612.py b/care/facility/migrations_old/0108_auto_20200510_1612.py similarity index 100% rename from care/facility/migrations/0108_auto_20200510_1612.py rename to care/facility/migrations_old/0108_auto_20200510_1612.py diff --git a/care/facility/migrations/0109_auto_20200511_2120.py b/care/facility/migrations_old/0109_auto_20200511_2120.py similarity index 100% rename from care/facility/migrations/0109_auto_20200511_2120.py rename to care/facility/migrations_old/0109_auto_20200511_2120.py diff --git a/care/facility/migrations/0110_populate_patient_search_ids.py b/care/facility/migrations_old/0110_populate_patient_search_ids.py similarity index 100% rename from care/facility/migrations/0110_populate_patient_search_ids.py rename to care/facility/migrations_old/0110_populate_patient_search_ids.py diff --git a/care/facility/migrations/0111_auto_20200511_2123.py b/care/facility/migrations_old/0111_auto_20200511_2123.py similarity index 100% rename from care/facility/migrations/0111_auto_20200511_2123.py rename to care/facility/migrations_old/0111_auto_20200511_2123.py diff --git a/care/facility/migrations/0112_auto_20200515_1738.py b/care/facility/migrations_old/0112_auto_20200515_1738.py similarity index 100% rename from care/facility/migrations/0112_auto_20200515_1738.py rename to care/facility/migrations_old/0112_auto_20200515_1738.py diff --git a/care/facility/migrations/0113_auto_20200519_0005.py b/care/facility/migrations_old/0113_auto_20200519_0005.py similarity index 100% rename from care/facility/migrations/0113_auto_20200519_0005.py rename to care/facility/migrations_old/0113_auto_20200519_0005.py diff --git a/care/facility/migrations/0114_auto_20200610_1720.py b/care/facility/migrations_old/0114_auto_20200610_1720.py similarity index 100% rename from care/facility/migrations/0114_auto_20200610_1720.py rename to care/facility/migrations_old/0114_auto_20200610_1720.py diff --git a/care/facility/migrations/0115_auto_20200611_1336.py b/care/facility/migrations_old/0115_auto_20200611_1336.py similarity index 100% rename from care/facility/migrations/0115_auto_20200611_1336.py rename to care/facility/migrations_old/0115_auto_20200611_1336.py diff --git a/care/facility/migrations/0116_facility_pincode.py b/care/facility/migrations_old/0116_facility_pincode.py similarity index 100% rename from care/facility/migrations/0116_facility_pincode.py rename to care/facility/migrations_old/0116_facility_pincode.py diff --git a/care/facility/migrations/0117_patientsample_icmr_category.py b/care/facility/migrations_old/0117_patientsample_icmr_category.py similarity index 100% rename from care/facility/migrations/0117_patientsample_icmr_category.py rename to care/facility/migrations_old/0117_patientsample_icmr_category.py diff --git a/care/facility/migrations/0118_auto_20200616_1051.py b/care/facility/migrations_old/0118_auto_20200616_1051.py similarity index 100% rename from care/facility/migrations/0118_auto_20200616_1051.py rename to care/facility/migrations_old/0118_auto_20200616_1051.py diff --git a/care/facility/migrations/0119_auto_20200617_1618.py b/care/facility/migrations_old/0119_auto_20200617_1618.py similarity index 100% rename from care/facility/migrations/0119_auto_20200617_1618.py rename to care/facility/migrations_old/0119_auto_20200617_1618.py diff --git a/care/facility/migrations/0120_patientsample_icmr_label.py b/care/facility/migrations_old/0120_patientsample_icmr_label.py similarity index 100% rename from care/facility/migrations/0120_patientsample_icmr_label.py rename to care/facility/migrations_old/0120_patientsample_icmr_label.py diff --git a/care/facility/migrations/0121_auto_20200619_2306.py b/care/facility/migrations_old/0121_auto_20200619_2306.py similarity index 100% rename from care/facility/migrations/0121_auto_20200619_2306.py rename to care/facility/migrations_old/0121_auto_20200619_2306.py diff --git a/care/facility/migrations/0122_auto_20200624_1127.py b/care/facility/migrations_old/0122_auto_20200624_1127.py similarity index 100% rename from care/facility/migrations/0122_auto_20200624_1127.py rename to care/facility/migrations_old/0122_auto_20200624_1127.py diff --git a/care/facility/migrations/0123_auto_20200626_0144.py b/care/facility/migrations_old/0123_auto_20200626_0144.py similarity index 100% rename from care/facility/migrations/0123_auto_20200626_0144.py rename to care/facility/migrations_old/0123_auto_20200626_0144.py diff --git a/care/facility/migrations/0124_populate_daily_round_ids.py b/care/facility/migrations_old/0124_populate_daily_round_ids.py similarity index 100% rename from care/facility/migrations/0124_populate_daily_round_ids.py rename to care/facility/migrations_old/0124_populate_daily_round_ids.py diff --git a/care/facility/migrations/0125_auto_20200626_0146.py b/care/facility/migrations_old/0125_auto_20200626_0146.py similarity index 100% rename from care/facility/migrations/0125_auto_20200626_0146.py rename to care/facility/migrations_old/0125_auto_20200626_0146.py diff --git a/care/facility/migrations/0126_auto_20200626_0156.py b/care/facility/migrations_old/0126_auto_20200626_0156.py similarity index 100% rename from care/facility/migrations/0126_auto_20200626_0156.py rename to care/facility/migrations_old/0126_auto_20200626_0156.py diff --git a/care/facility/migrations/0127_patientsearch_is_active.py b/care/facility/migrations_old/0127_patientsearch_is_active.py similarity index 100% rename from care/facility/migrations/0127_patientsearch_is_active.py rename to care/facility/migrations_old/0127_patientsearch_is_active.py diff --git a/care/facility/migrations/0128_facilityrelatedsummary.py b/care/facility/migrations_old/0128_facilityrelatedsummary.py similarity index 100% rename from care/facility/migrations/0128_facilityrelatedsummary.py rename to care/facility/migrations_old/0128_facilityrelatedsummary.py diff --git a/care/facility/migrations/0129_auto_20200706_1912.py b/care/facility/migrations_old/0129_auto_20200706_1912.py similarity index 100% rename from care/facility/migrations/0129_auto_20200706_1912.py rename to care/facility/migrations_old/0129_auto_20200706_1912.py diff --git a/care/facility/migrations/0130_auto_20200706_1946.py b/care/facility/migrations_old/0130_auto_20200706_1946.py similarity index 100% rename from care/facility/migrations/0130_auto_20200706_1946.py rename to care/facility/migrations_old/0130_auto_20200706_1946.py diff --git a/care/facility/migrations/0131_auto_20200706_1954.py b/care/facility/migrations_old/0131_auto_20200706_1954.py similarity index 100% rename from care/facility/migrations/0131_auto_20200706_1954.py rename to care/facility/migrations_old/0131_auto_20200706_1954.py diff --git a/care/facility/migrations/0132_patientsample_testing_facility.py b/care/facility/migrations_old/0132_patientsample_testing_facility.py similarity index 100% rename from care/facility/migrations/0132_patientsample_testing_facility.py rename to care/facility/migrations_old/0132_patientsample_testing_facility.py diff --git a/care/facility/migrations/0133_auto_20200710_2355.py b/care/facility/migrations_old/0133_auto_20200710_2355.py similarity index 100% rename from care/facility/migrations/0133_auto_20200710_2355.py rename to care/facility/migrations_old/0133_auto_20200710_2355.py diff --git a/care/facility/migrations/0134_auto_20200713_1756.py b/care/facility/migrations_old/0134_auto_20200713_1756.py similarity index 100% rename from care/facility/migrations/0134_auto_20200713_1756.py rename to care/facility/migrations_old/0134_auto_20200713_1756.py diff --git a/care/facility/migrations/0135_auto_20200715_1433.py b/care/facility/migrations_old/0135_auto_20200715_1433.py similarity index 100% rename from care/facility/migrations/0135_auto_20200715_1433.py rename to care/facility/migrations_old/0135_auto_20200715_1433.py diff --git a/care/facility/migrations/0136_auto_20200716_1003.py b/care/facility/migrations_old/0136_auto_20200716_1003.py similarity index 100% rename from care/facility/migrations/0136_auto_20200716_1003.py rename to care/facility/migrations_old/0136_auto_20200716_1003.py diff --git a/care/facility/migrations/0137_auto_20200718_0654.py b/care/facility/migrations_old/0137_auto_20200718_0654.py similarity index 100% rename from care/facility/migrations/0137_auto_20200718_0654.py rename to care/facility/migrations_old/0137_auto_20200718_0654.py diff --git a/care/facility/migrations/0138_auto_20200720_2227.py b/care/facility/migrations_old/0138_auto_20200720_2227.py similarity index 100% rename from care/facility/migrations/0138_auto_20200720_2227.py rename to care/facility/migrations_old/0138_auto_20200720_2227.py diff --git a/care/facility/migrations/0139_shiftingrequest.py b/care/facility/migrations_old/0139_shiftingrequest.py similarity index 100% rename from care/facility/migrations/0139_shiftingrequest.py rename to care/facility/migrations_old/0139_shiftingrequest.py diff --git a/care/facility/migrations/0140_auto_20200723_2355.py b/care/facility/migrations_old/0140_auto_20200723_2355.py similarity index 100% rename from care/facility/migrations/0140_auto_20200723_2355.py rename to care/facility/migrations_old/0140_auto_20200723_2355.py diff --git a/care/facility/migrations/0141_facilityrelatedsummary_modified_date.py b/care/facility/migrations_old/0141_facilityrelatedsummary_modified_date.py similarity index 100% rename from care/facility/migrations/0141_facilityrelatedsummary_modified_date.py rename to care/facility/migrations_old/0141_facilityrelatedsummary_modified_date.py diff --git a/care/facility/migrations/0142_shiftingrequest_patient.py b/care/facility/migrations_old/0142_shiftingrequest_patient.py similarity index 100% rename from care/facility/migrations/0142_shiftingrequest_patient.py rename to care/facility/migrations_old/0142_shiftingrequest_patient.py diff --git a/care/facility/migrations/0143_auto_20200731_1217.py b/care/facility/migrations_old/0143_auto_20200731_1217.py similarity index 100% rename from care/facility/migrations/0143_auto_20200731_1217.py rename to care/facility/migrations_old/0143_auto_20200731_1217.py diff --git a/care/facility/migrations/0144_patientmobileotp.py b/care/facility/migrations_old/0144_patientmobileotp.py similarity index 100% rename from care/facility/migrations/0144_patientmobileotp.py rename to care/facility/migrations_old/0144_patientmobileotp.py diff --git a/care/facility/migrations/0145_auto_20200731_1913.py b/care/facility/migrations_old/0145_auto_20200731_1913.py similarity index 100% rename from care/facility/migrations/0145_auto_20200731_1913.py rename to care/facility/migrations_old/0145_auto_20200731_1913.py diff --git a/care/facility/migrations/0146_auto_20200801_1844.py b/care/facility/migrations_old/0146_auto_20200801_1844.py similarity index 100% rename from care/facility/migrations/0146_auto_20200801_1844.py rename to care/facility/migrations_old/0146_auto_20200801_1844.py diff --git a/care/facility/migrations/0147_auto_20200802_2134.py b/care/facility/migrations_old/0147_auto_20200802_2134.py similarity index 100% rename from care/facility/migrations/0147_auto_20200802_2134.py rename to care/facility/migrations_old/0147_auto_20200802_2134.py diff --git a/care/facility/migrations/0148_populate_unencrypted_patients.py b/care/facility/migrations_old/0148_populate_unencrypted_patients.py similarity index 100% rename from care/facility/migrations/0148_populate_unencrypted_patients.py rename to care/facility/migrations_old/0148_populate_unencrypted_patients.py diff --git a/care/facility/migrations/0149_auto_20200802_2156.py b/care/facility/migrations_old/0149_auto_20200802_2156.py similarity index 100% rename from care/facility/migrations/0149_auto_20200802_2156.py rename to care/facility/migrations_old/0149_auto_20200802_2156.py diff --git a/care/facility/migrations/0150_auto_20200802_2156.py b/care/facility/migrations_old/0150_auto_20200802_2156.py similarity index 100% rename from care/facility/migrations/0150_auto_20200802_2156.py rename to care/facility/migrations_old/0150_auto_20200802_2156.py diff --git a/care/facility/migrations/0151_auto_20200802_2207.py b/care/facility/migrations_old/0151_auto_20200802_2207.py similarity index 100% rename from care/facility/migrations/0151_auto_20200802_2207.py rename to care/facility/migrations_old/0151_auto_20200802_2207.py diff --git a/care/facility/migrations/0152_auto_20200805_1906.py b/care/facility/migrations_old/0152_auto_20200805_1906.py similarity index 100% rename from care/facility/migrations/0152_auto_20200805_1906.py rename to care/facility/migrations_old/0152_auto_20200805_1906.py diff --git a/care/facility/migrations/0153_auto_20200805_2226.py b/care/facility/migrations_old/0153_auto_20200805_2226.py similarity index 100% rename from care/facility/migrations/0153_auto_20200805_2226.py rename to care/facility/migrations_old/0153_auto_20200805_2226.py diff --git a/care/facility/migrations/0154_populate_patients_last_consultation.py b/care/facility/migrations_old/0154_populate_patients_last_consultation.py similarity index 100% rename from care/facility/migrations/0154_populate_patients_last_consultation.py rename to care/facility/migrations_old/0154_populate_patients_last_consultation.py diff --git a/care/facility/migrations/0155_auto_20200805_2312.py b/care/facility/migrations_old/0155_auto_20200805_2312.py similarity index 100% rename from care/facility/migrations/0155_auto_20200805_2312.py rename to care/facility/migrations_old/0155_auto_20200805_2312.py diff --git a/care/facility/migrations/0156_auto_20200808_2205.py b/care/facility/migrations_old/0156_auto_20200808_2205.py similarity index 100% rename from care/facility/migrations/0156_auto_20200808_2205.py rename to care/facility/migrations_old/0156_auto_20200808_2205.py diff --git a/care/facility/migrations/0157_patientconsultation_ip_no.py b/care/facility/migrations_old/0157_patientconsultation_ip_no.py similarity index 100% rename from care/facility/migrations/0157_patientconsultation_ip_no.py rename to care/facility/migrations_old/0157_patientconsultation_ip_no.py diff --git a/care/facility/migrations/0158_auto_20200809_1140.py b/care/facility/migrations_old/0158_auto_20200809_1140.py similarity index 100% rename from care/facility/migrations/0158_auto_20200809_1140.py rename to care/facility/migrations_old/0158_auto_20200809_1140.py diff --git a/care/facility/migrations/0159_patientconsultation_is_telemedicine.py b/care/facility/migrations_old/0159_patientconsultation_is_telemedicine.py similarity index 100% rename from care/facility/migrations/0159_patientconsultation_is_telemedicine.py rename to care/facility/migrations_old/0159_patientconsultation_is_telemedicine.py diff --git a/care/facility/migrations/0160_patientconsultation_doctor.py b/care/facility/migrations_old/0160_patientconsultation_doctor.py similarity index 100% rename from care/facility/migrations/0160_patientconsultation_doctor.py rename to care/facility/migrations_old/0160_patientconsultation_doctor.py diff --git a/care/facility/migrations/0161_auto_20200810_1338.py b/care/facility/migrations_old/0161_auto_20200810_1338.py similarity index 100% rename from care/facility/migrations/0161_auto_20200810_1338.py rename to care/facility/migrations_old/0161_auto_20200810_1338.py diff --git a/care/facility/migrations/0162_auto_20200811_1101.py b/care/facility/migrations_old/0162_auto_20200811_1101.py similarity index 100% rename from care/facility/migrations/0162_auto_20200811_1101.py rename to care/facility/migrations_old/0162_auto_20200811_1101.py diff --git a/care/facility/migrations/0163_auto_20200811_1115.py b/care/facility/migrations_old/0163_auto_20200811_1115.py similarity index 100% rename from care/facility/migrations/0163_auto_20200811_1115.py rename to care/facility/migrations_old/0163_auto_20200811_1115.py diff --git a/care/facility/migrations/0164_auto_20200811_1157.py b/care/facility/migrations_old/0164_auto_20200811_1157.py similarity index 100% rename from care/facility/migrations/0164_auto_20200811_1157.py rename to care/facility/migrations_old/0164_auto_20200811_1157.py diff --git a/care/facility/migrations/0165_facilitypatientstatshistory_num_patient_confirmed_positive.py b/care/facility/migrations_old/0165_facilitypatientstatshistory_num_patient_confirmed_positive.py similarity index 100% rename from care/facility/migrations/0165_facilitypatientstatshistory_num_patient_confirmed_positive.py rename to care/facility/migrations_old/0165_facilitypatientstatshistory_num_patient_confirmed_positive.py diff --git a/care/facility/migrations/0166_auto_20200815_1930.py b/care/facility/migrations_old/0166_auto_20200815_1930.py similarity index 100% rename from care/facility/migrations/0166_auto_20200815_1930.py rename to care/facility/migrations_old/0166_auto_20200815_1930.py diff --git a/care/facility/migrations/0167_auto_20200830_1121.py b/care/facility/migrations_old/0167_auto_20200830_1121.py similarity index 100% rename from care/facility/migrations/0167_auto_20200830_1121.py rename to care/facility/migrations_old/0167_auto_20200830_1121.py diff --git a/care/facility/migrations/0168_auto_20200830_1222.py b/care/facility/migrations_old/0168_auto_20200830_1222.py similarity index 100% rename from care/facility/migrations/0168_auto_20200830_1222.py rename to care/facility/migrations_old/0168_auto_20200830_1222.py diff --git a/care/facility/migrations/0169_auto_20200830_1232.py b/care/facility/migrations_old/0169_auto_20200830_1232.py similarity index 100% rename from care/facility/migrations/0169_auto_20200830_1232.py rename to care/facility/migrations_old/0169_auto_20200830_1232.py diff --git a/care/facility/migrations/0170_patientconsultation_test_id.py b/care/facility/migrations_old/0170_patientconsultation_test_id.py similarity index 100% rename from care/facility/migrations/0170_patientconsultation_test_id.py rename to care/facility/migrations_old/0170_patientconsultation_test_id.py diff --git a/care/facility/migrations/0171_auto_20200901_2205.py b/care/facility/migrations_old/0171_auto_20200901_2205.py similarity index 100% rename from care/facility/migrations/0171_auto_20200901_2205.py rename to care/facility/migrations_old/0171_auto_20200901_2205.py diff --git a/care/facility/migrations/0172_auto_20200903_1617.py b/care/facility/migrations_old/0172_auto_20200903_1617.py similarity index 100% rename from care/facility/migrations/0172_auto_20200903_1617.py rename to care/facility/migrations_old/0172_auto_20200903_1617.py diff --git a/care/facility/migrations/0173_auto_20200903_1625.py b/care/facility/migrations_old/0173_auto_20200903_1625.py similarity index 100% rename from care/facility/migrations/0173_auto_20200903_1625.py rename to care/facility/migrations_old/0173_auto_20200903_1625.py diff --git a/care/facility/migrations/0174_auto_20200903_1836.py b/care/facility/migrations_old/0174_auto_20200903_1836.py similarity index 100% rename from care/facility/migrations/0174_auto_20200903_1836.py rename to care/facility/migrations_old/0174_auto_20200903_1836.py diff --git a/care/facility/migrations/0175_auto_20200904_1000.py b/care/facility/migrations_old/0175_auto_20200904_1000.py similarity index 100% rename from care/facility/migrations/0175_auto_20200904_1000.py rename to care/facility/migrations_old/0175_auto_20200904_1000.py diff --git a/care/facility/migrations/0176_auto_20200916_1443.py b/care/facility/migrations_old/0176_auto_20200916_1443.py similarity index 100% rename from care/facility/migrations/0176_auto_20200916_1443.py rename to care/facility/migrations_old/0176_auto_20200916_1443.py diff --git a/care/facility/migrations/0177_auto_20200916_1448.py b/care/facility/migrations_old/0177_auto_20200916_1448.py similarity index 100% rename from care/facility/migrations/0177_auto_20200916_1448.py rename to care/facility/migrations_old/0177_auto_20200916_1448.py diff --git a/care/facility/migrations/0178_auto_20200916_1534.py b/care/facility/migrations_old/0178_auto_20200916_1534.py similarity index 100% rename from care/facility/migrations/0178_auto_20200916_1534.py rename to care/facility/migrations_old/0178_auto_20200916_1534.py diff --git a/care/facility/migrations/0179_auto_20200918_1132.py b/care/facility/migrations_old/0179_auto_20200918_1132.py similarity index 100% rename from care/facility/migrations/0179_auto_20200918_1132.py rename to care/facility/migrations_old/0179_auto_20200918_1132.py diff --git a/care/facility/migrations/0180_facility_ward.py b/care/facility/migrations_old/0180_facility_ward.py similarity index 100% rename from care/facility/migrations/0180_facility_ward.py rename to care/facility/migrations_old/0180_facility_ward.py diff --git a/care/facility/migrations/0181_auto_20200921_1754.py b/care/facility/migrations_old/0181_auto_20200921_1754.py similarity index 100% rename from care/facility/migrations/0181_auto_20200921_1754.py rename to care/facility/migrations_old/0181_auto_20200921_1754.py diff --git a/care/facility/migrations/0182_auto_20200921_1756.py b/care/facility/migrations_old/0182_auto_20200921_1756.py similarity index 100% rename from care/facility/migrations/0182_auto_20200921_1756.py rename to care/facility/migrations_old/0182_auto_20200921_1756.py diff --git a/care/facility/migrations/0183_shiftingrequest_is_kasp.py b/care/facility/migrations_old/0183_shiftingrequest_is_kasp.py similarity index 100% rename from care/facility/migrations/0183_shiftingrequest_is_kasp.py rename to care/facility/migrations_old/0183_shiftingrequest_is_kasp.py diff --git a/care/facility/migrations/0184_auto_20200925_2353.py b/care/facility/migrations_old/0184_auto_20200925_2353.py similarity index 100% rename from care/facility/migrations/0184_auto_20200925_2353.py rename to care/facility/migrations_old/0184_auto_20200925_2353.py diff --git a/care/facility/migrations/0185_correct_blood_donation.py b/care/facility/migrations_old/0185_correct_blood_donation.py similarity index 100% rename from care/facility/migrations/0185_correct_blood_donation.py rename to care/facility/migrations_old/0185_correct_blood_donation.py diff --git a/care/facility/migrations/0186_auto_20200926_0001.py b/care/facility/migrations_old/0186_auto_20200926_0001.py similarity index 100% rename from care/facility/migrations/0186_auto_20200926_0001.py rename to care/facility/migrations_old/0186_auto_20200926_0001.py diff --git a/care/facility/migrations/0187_patientexternaltest.py b/care/facility/migrations_old/0187_patientexternaltest.py similarity index 100% rename from care/facility/migrations/0187_patientexternaltest.py rename to care/facility/migrations_old/0187_patientexternaltest.py diff --git a/care/facility/migrations/0188_auto_20200928_0139.py b/care/facility/migrations_old/0188_auto_20200928_0139.py similarity index 100% rename from care/facility/migrations/0188_auto_20200928_0139.py rename to care/facility/migrations_old/0188_auto_20200928_0139.py diff --git a/care/facility/migrations/0189_auto_20200929_1258.py b/care/facility/migrations_old/0189_auto_20200929_1258.py similarity index 100% rename from care/facility/migrations/0189_auto_20200929_1258.py rename to care/facility/migrations_old/0189_auto_20200929_1258.py diff --git a/care/facility/migrations/0190_auto_20201001_1134.py b/care/facility/migrations_old/0190_auto_20201001_1134.py similarity index 100% rename from care/facility/migrations/0190_auto_20201001_1134.py rename to care/facility/migrations_old/0190_auto_20201001_1134.py diff --git a/care/facility/migrations/0191_dailyround_spo2.py b/care/facility/migrations_old/0191_dailyround_spo2.py similarity index 100% rename from care/facility/migrations/0191_dailyround_spo2.py rename to care/facility/migrations_old/0191_dailyround_spo2.py diff --git a/care/facility/migrations/0192_auto_20201004_1457.py b/care/facility/migrations_old/0192_auto_20201004_1457.py similarity index 100% rename from care/facility/migrations/0192_auto_20201004_1457.py rename to care/facility/migrations_old/0192_auto_20201004_1457.py diff --git a/care/facility/migrations/0193_auto_20201004_1458.py b/care/facility/migrations_old/0193_auto_20201004_1458.py similarity index 100% rename from care/facility/migrations/0193_auto_20201004_1458.py rename to care/facility/migrations_old/0193_auto_20201004_1458.py diff --git a/care/facility/migrations/0194_auto_20201009_1936.py b/care/facility/migrations_old/0194_auto_20201009_1936.py similarity index 100% rename from care/facility/migrations/0194_auto_20201009_1936.py rename to care/facility/migrations_old/0194_auto_20201009_1936.py diff --git a/care/facility/migrations/0195_auto_20201009_1939.py b/care/facility/migrations_old/0195_auto_20201009_1939.py similarity index 100% rename from care/facility/migrations/0195_auto_20201009_1939.py rename to care/facility/migrations_old/0195_auto_20201009_1939.py diff --git a/care/facility/migrations/0196_auto_20201011_2219.py b/care/facility/migrations_old/0196_auto_20201011_2219.py similarity index 100% rename from care/facility/migrations/0196_auto_20201011_2219.py rename to care/facility/migrations_old/0196_auto_20201011_2219.py diff --git a/care/facility/migrations/0197_auto_20201011_2338.py b/care/facility/migrations_old/0197_auto_20201011_2338.py similarity index 100% rename from care/facility/migrations/0197_auto_20201011_2338.py rename to care/facility/migrations_old/0197_auto_20201011_2338.py diff --git a/care/facility/migrations/0198_shiftingrequest_is_assigned_to_user.py b/care/facility/migrations_old/0198_shiftingrequest_is_assigned_to_user.py similarity index 100% rename from care/facility/migrations/0198_shiftingrequest_is_assigned_to_user.py rename to care/facility/migrations_old/0198_shiftingrequest_is_assigned_to_user.py diff --git a/care/facility/migrations/0199_shiftingrequest_assigned_to.py b/care/facility/migrations_old/0199_shiftingrequest_assigned_to.py similarity index 100% rename from care/facility/migrations/0199_shiftingrequest_assigned_to.py rename to care/facility/migrations_old/0199_shiftingrequest_assigned_to.py diff --git a/care/facility/migrations/0200_dailyround_admitted_to.py b/care/facility/migrations_old/0200_dailyround_admitted_to.py similarity index 100% rename from care/facility/migrations/0200_dailyround_admitted_to.py rename to care/facility/migrations_old/0200_dailyround_admitted_to.py diff --git a/care/facility/migrations/0201_populate_admitted_to_daily_round.py b/care/facility/migrations_old/0201_populate_admitted_to_daily_round.py similarity index 100% rename from care/facility/migrations/0201_populate_admitted_to_daily_round.py rename to care/facility/migrations_old/0201_populate_admitted_to_daily_round.py diff --git a/care/facility/migrations/0202_auto_20201024_1956.py b/care/facility/migrations_old/0202_auto_20201024_1956.py similarity index 100% rename from care/facility/migrations/0202_auto_20201024_1956.py rename to care/facility/migrations_old/0202_auto_20201024_1956.py diff --git a/care/facility/migrations/0203_auto_20201024_2024.py b/care/facility/migrations_old/0203_auto_20201024_2024.py similarity index 100% rename from care/facility/migrations/0203_auto_20201024_2024.py rename to care/facility/migrations_old/0203_auto_20201024_2024.py diff --git a/care/facility/migrations/0204_auto_20201024_2052.py b/care/facility/migrations_old/0204_auto_20201024_2052.py similarity index 100% rename from care/facility/migrations/0204_auto_20201024_2052.py rename to care/facility/migrations_old/0204_auto_20201024_2052.py diff --git a/care/facility/migrations/0205_auto_20201025_1709.py b/care/facility/migrations_old/0205_auto_20201025_1709.py similarity index 100% rename from care/facility/migrations/0205_auto_20201025_1709.py rename to care/facility/migrations_old/0205_auto_20201025_1709.py diff --git a/care/facility/migrations/0206_notification.py b/care/facility/migrations_old/0206_notification.py similarity index 100% rename from care/facility/migrations/0206_notification.py rename to care/facility/migrations_old/0206_notification.py diff --git a/care/facility/migrations/0207_auto_20201123_0056.py b/care/facility/migrations_old/0207_auto_20201123_0056.py similarity index 100% rename from care/facility/migrations/0207_auto_20201123_0056.py rename to care/facility/migrations_old/0207_auto_20201123_0056.py diff --git a/care/facility/migrations/0208_notification_caused_objects.py b/care/facility/migrations_old/0208_notification_caused_objects.py similarity index 100% rename from care/facility/migrations/0208_notification_caused_objects.py rename to care/facility/migrations_old/0208_notification_caused_objects.py diff --git a/care/facility/migrations/0209_auto_20201123_1132.py b/care/facility/migrations_old/0209_auto_20201123_1132.py similarity index 100% rename from care/facility/migrations/0209_auto_20201123_1132.py rename to care/facility/migrations_old/0209_auto_20201123_1132.py diff --git a/care/facility/migrations/0210_remove_notification_caused_object_external_id.py b/care/facility/migrations_old/0210_remove_notification_caused_object_external_id.py similarity index 100% rename from care/facility/migrations/0210_remove_notification_caused_object_external_id.py rename to care/facility/migrations_old/0210_remove_notification_caused_object_external_id.py diff --git a/care/facility/migrations/0211_auto_20201214_1014.py b/care/facility/migrations_old/0211_auto_20201214_1014.py similarity index 100% rename from care/facility/migrations/0211_auto_20201214_1014.py rename to care/facility/migrations_old/0211_auto_20201214_1014.py diff --git a/care/facility/migrations/0212_auto_20201223_1617.py b/care/facility/migrations_old/0212_auto_20201223_1617.py similarity index 100% rename from care/facility/migrations/0212_auto_20201223_1617.py rename to care/facility/migrations_old/0212_auto_20201223_1617.py diff --git a/care/facility/migrations/0213_auto_20210107_1310.py b/care/facility/migrations_old/0213_auto_20210107_1310.py similarity index 100% rename from care/facility/migrations/0213_auto_20210107_1310.py rename to care/facility/migrations_old/0213_auto_20210107_1310.py diff --git a/care/facility/migrations/0214_auto_20210129_2250.py b/care/facility/migrations_old/0214_auto_20210129_2250.py similarity index 100% rename from care/facility/migrations/0214_auto_20210129_2250.py rename to care/facility/migrations_old/0214_auto_20210129_2250.py diff --git a/care/facility/migrations/0215_auto_20210130_2236.py b/care/facility/migrations_old/0215_auto_20210130_2236.py similarity index 100% rename from care/facility/migrations/0215_auto_20210130_2236.py rename to care/facility/migrations_old/0215_auto_20210130_2236.py diff --git a/care/facility/migrations/0216_auto_20210201_2228.py b/care/facility/migrations_old/0216_auto_20210201_2228.py similarity index 100% rename from care/facility/migrations/0216_auto_20210201_2228.py rename to care/facility/migrations_old/0216_auto_20210201_2228.py diff --git a/care/facility/migrations/0217_investigationsession_investigationvalue_patientinvestigation_patientinvestigationgroup.py b/care/facility/migrations_old/0217_investigationsession_investigationvalue_patientinvestigation_patientinvestigationgroup.py similarity index 100% rename from care/facility/migrations/0217_investigationsession_investigationvalue_patientinvestigation_patientinvestigationgroup.py rename to care/facility/migrations_old/0217_investigationsession_investigationvalue_patientinvestigation_patientinvestigationgroup.py diff --git a/care/facility/migrations/0218_auto_20210417_2354.py b/care/facility/migrations_old/0218_auto_20210417_2354.py similarity index 100% rename from care/facility/migrations/0218_auto_20210417_2354.py rename to care/facility/migrations_old/0218_auto_20210417_2354.py diff --git a/care/facility/migrations/0219_remove_investigationsession_session.py b/care/facility/migrations_old/0219_remove_investigationsession_session.py similarity index 100% rename from care/facility/migrations/0219_remove_investigationsession_session.py rename to care/facility/migrations_old/0219_remove_investigationsession_session.py diff --git a/care/facility/migrations/0220_populate_investigations.py b/care/facility/migrations_old/0220_populate_investigations.py similarity index 100% rename from care/facility/migrations/0220_populate_investigations.py rename to care/facility/migrations_old/0220_populate_investigations.py diff --git a/care/facility/migrations/0221_auto_20210426_1153.py b/care/facility/migrations_old/0221_auto_20210426_1153.py similarity index 100% rename from care/facility/migrations/0221_auto_20210426_1153.py rename to care/facility/migrations_old/0221_auto_20210426_1153.py diff --git a/care/facility/migrations/0221_facility_kasp_empanelled.py b/care/facility/migrations_old/0221_facility_kasp_empanelled.py similarity index 100% rename from care/facility/migrations/0221_facility_kasp_empanelled.py rename to care/facility/migrations_old/0221_facility_kasp_empanelled.py diff --git a/care/facility/migrations/0221_investigationsession_created_by.py b/care/facility/migrations_old/0221_investigationsession_created_by.py similarity index 100% rename from care/facility/migrations/0221_investigationsession_created_by.py rename to care/facility/migrations_old/0221_investigationsession_created_by.py diff --git a/care/facility/migrations/0222_auto_20210427_0002.py b/care/facility/migrations_old/0222_auto_20210427_0002.py similarity index 100% rename from care/facility/migrations/0222_auto_20210427_0002.py rename to care/facility/migrations_old/0222_auto_20210427_0002.py diff --git a/care/facility/migrations/0222_auto_20210501_0958.py b/care/facility/migrations_old/0222_auto_20210501_0958.py similarity index 100% rename from care/facility/migrations/0222_auto_20210501_0958.py rename to care/facility/migrations_old/0222_auto_20210501_0958.py diff --git a/care/facility/migrations/0223_merge_20210427_1419.py b/care/facility/migrations_old/0223_merge_20210427_1419.py similarity index 100% rename from care/facility/migrations/0223_merge_20210427_1419.py rename to care/facility/migrations_old/0223_merge_20210427_1419.py diff --git a/care/facility/migrations/0224_change_disease_status_from_recover_to_recovered.py b/care/facility/migrations_old/0224_change_disease_status_from_recover_to_recovered.py similarity index 93% rename from care/facility/migrations/0224_change_disease_status_from_recover_to_recovered.py rename to care/facility/migrations_old/0224_change_disease_status_from_recover_to_recovered.py index ee9b679733..7f5a85152b 100644 --- a/care/facility/migrations/0224_change_disease_status_from_recover_to_recovered.py +++ b/care/facility/migrations_old/0224_change_disease_status_from_recover_to_recovered.py @@ -1,4 +1,4 @@ -from django.db import migrations, models +from django.db import migrations from care.facility.models.patient_base import DiseaseStatusEnum diff --git a/care/facility/migrations/0225_facilityinventorylog_current_stock.py b/care/facility/migrations_old/0225_facilityinventorylog_current_stock.py similarity index 100% rename from care/facility/migrations/0225_facilityinventorylog_current_stock.py rename to care/facility/migrations_old/0225_facilityinventorylog_current_stock.py diff --git a/care/facility/migrations/0226_facilityinventorylog_quantity_in_default_unit.py b/care/facility/migrations_old/0226_facilityinventorylog_quantity_in_default_unit.py similarity index 100% rename from care/facility/migrations/0226_facilityinventorylog_quantity_in_default_unit.py rename to care/facility/migrations_old/0226_facilityinventorylog_quantity_in_default_unit.py diff --git a/care/facility/migrations/0227_auto_20210505_2055.py b/care/facility/migrations_old/0227_auto_20210505_2055.py similarity index 100% rename from care/facility/migrations/0227_auto_20210505_2055.py rename to care/facility/migrations_old/0227_auto_20210505_2055.py diff --git a/care/facility/migrations/0227_auto_20210506_1409.py b/care/facility/migrations_old/0227_auto_20210506_1409.py similarity index 100% rename from care/facility/migrations/0227_auto_20210506_1409.py rename to care/facility/migrations_old/0227_auto_20210506_1409.py diff --git a/care/facility/migrations/0228_shiftingrequest_breathlessness_level.py b/care/facility/migrations_old/0228_shiftingrequest_breathlessness_level.py similarity index 100% rename from care/facility/migrations/0228_shiftingrequest_breathlessness_level.py rename to care/facility/migrations_old/0228_shiftingrequest_breathlessness_level.py diff --git a/care/facility/migrations/0229_merge_20210506_1549.py b/care/facility/migrations_old/0229_merge_20210506_1549.py similarity index 100% rename from care/facility/migrations/0229_merge_20210506_1549.py rename to care/facility/migrations_old/0229_merge_20210506_1549.py diff --git a/care/facility/migrations/0230_facility_expected_oxygen_requirement.py b/care/facility/migrations_old/0230_facility_expected_oxygen_requirement.py similarity index 100% rename from care/facility/migrations/0230_facility_expected_oxygen_requirement.py rename to care/facility/migrations_old/0230_facility_expected_oxygen_requirement.py diff --git a/care/facility/migrations/0231_auto_20210508_2214.py b/care/facility/migrations_old/0231_auto_20210508_2214.py similarity index 100% rename from care/facility/migrations/0231_auto_20210508_2214.py rename to care/facility/migrations_old/0231_auto_20210508_2214.py diff --git a/care/facility/migrations/0232_auto_20210510_1218.py b/care/facility/migrations_old/0232_auto_20210510_1218.py similarity index 100% rename from care/facility/migrations/0232_auto_20210510_1218.py rename to care/facility/migrations_old/0232_auto_20210510_1218.py diff --git a/care/facility/migrations/0233_auto_20210510_1832.py b/care/facility/migrations_old/0233_auto_20210510_1832.py similarity index 100% rename from care/facility/migrations/0233_auto_20210510_1832.py rename to care/facility/migrations_old/0233_auto_20210510_1832.py diff --git a/care/facility/migrations/0234_auto_20210511_2058.py b/care/facility/migrations_old/0234_auto_20210511_2058.py similarity index 100% rename from care/facility/migrations/0234_auto_20210511_2058.py rename to care/facility/migrations_old/0234_auto_20210511_2058.py diff --git a/care/facility/migrations/0235_merge_20210513_1316.py b/care/facility/migrations_old/0235_merge_20210513_1316.py similarity index 100% rename from care/facility/migrations/0235_merge_20210513_1316.py rename to care/facility/migrations_old/0235_merge_20210513_1316.py diff --git a/care/facility/migrations/0236_auto_20210513_1336.py b/care/facility/migrations_old/0236_auto_20210513_1336.py similarity index 100% rename from care/facility/migrations/0236_auto_20210513_1336.py rename to care/facility/migrations_old/0236_auto_20210513_1336.py diff --git a/care/facility/migrations/0237_dailyround_created_by_telemedicine.py b/care/facility/migrations_old/0237_dailyround_created_by_telemedicine.py similarity index 100% rename from care/facility/migrations/0237_dailyround_created_by_telemedicine.py rename to care/facility/migrations_old/0237_dailyround_created_by_telemedicine.py diff --git a/care/facility/migrations/0238_fileupload_file_category.py b/care/facility/migrations_old/0238_fileupload_file_category.py similarity index 100% rename from care/facility/migrations/0238_fileupload_file_category.py rename to care/facility/migrations_old/0238_fileupload_file_category.py diff --git a/care/facility/migrations/0239_patientconsultation_is_kasp.py b/care/facility/migrations_old/0239_patientconsultation_is_kasp.py similarity index 100% rename from care/facility/migrations/0239_patientconsultation_is_kasp.py rename to care/facility/migrations_old/0239_patientconsultation_is_kasp.py diff --git a/care/facility/migrations/0240_patientconsultation_kasp_enabled_date.py b/care/facility/migrations_old/0240_patientconsultation_kasp_enabled_date.py similarity index 100% rename from care/facility/migrations/0240_patientconsultation_kasp_enabled_date.py rename to care/facility/migrations_old/0240_patientconsultation_kasp_enabled_date.py diff --git a/care/facility/migrations/0241_auto_20210519_0115.py b/care/facility/migrations_old/0241_auto_20210519_0115.py similarity index 100% rename from care/facility/migrations/0241_auto_20210519_0115.py rename to care/facility/migrations_old/0241_auto_20210519_0115.py diff --git a/care/facility/migrations/0242_auto_20210523_1310.py b/care/facility/migrations_old/0242_auto_20210523_1310.py similarity index 100% rename from care/facility/migrations/0242_auto_20210523_1310.py rename to care/facility/migrations_old/0242_auto_20210523_1310.py diff --git a/care/facility/migrations/0243_auto_20210524_2245.py b/care/facility/migrations_old/0243_auto_20210524_2245.py similarity index 100% rename from care/facility/migrations/0243_auto_20210524_2245.py rename to care/facility/migrations_old/0243_auto_20210524_2245.py diff --git a/care/facility/migrations/0244_resourcerequest_title.py b/care/facility/migrations_old/0244_resourcerequest_title.py similarity index 100% rename from care/facility/migrations/0244_resourcerequest_title.py rename to care/facility/migrations_old/0244_resourcerequest_title.py diff --git a/care/facility/migrations/0245_auto_20210525_0130.py b/care/facility/migrations_old/0245_auto_20210525_0130.py similarity index 100% rename from care/facility/migrations/0245_auto_20210525_0130.py rename to care/facility/migrations_old/0245_auto_20210525_0130.py diff --git a/care/facility/migrations/0246_facilityinventorylog_probable_accident.py b/care/facility/migrations_old/0246_facilityinventorylog_probable_accident.py similarity index 100% rename from care/facility/migrations/0246_facilityinventorylog_probable_accident.py rename to care/facility/migrations_old/0246_facilityinventorylog_probable_accident.py diff --git a/care/facility/migrations/0247_auto_20210526_1922.py b/care/facility/migrations_old/0247_auto_20210526_1922.py similarity index 100% rename from care/facility/migrations/0247_auto_20210526_1922.py rename to care/facility/migrations_old/0247_auto_20210526_1922.py diff --git a/care/facility/migrations/0248_auto_20210529_1957.py b/care/facility/migrations_old/0248_auto_20210529_1957.py similarity index 100% rename from care/facility/migrations/0248_auto_20210529_1957.py rename to care/facility/migrations_old/0248_auto_20210529_1957.py diff --git a/care/facility/migrations/0249_auto_20210529_2031.py b/care/facility/migrations_old/0249_auto_20210529_2031.py similarity index 100% rename from care/facility/migrations/0249_auto_20210529_2031.py rename to care/facility/migrations_old/0249_auto_20210529_2031.py diff --git a/care/facility/migrations/0250_auto_20210603_0359.py b/care/facility/migrations_old/0250_auto_20210603_0359.py similarity index 100% rename from care/facility/migrations/0250_auto_20210603_0359.py rename to care/facility/migrations_old/0250_auto_20210603_0359.py diff --git a/care/facility/migrations/0251_auto_20210607_2009.py b/care/facility/migrations_old/0251_auto_20210607_2009.py similarity index 100% rename from care/facility/migrations/0251_auto_20210607_2009.py rename to care/facility/migrations_old/0251_auto_20210607_2009.py diff --git a/care/facility/migrations/0252_auto_20210609_2332.py b/care/facility/migrations_old/0252_auto_20210609_2332.py similarity index 100% rename from care/facility/migrations/0252_auto_20210609_2332.py rename to care/facility/migrations_old/0252_auto_20210609_2332.py diff --git a/care/facility/migrations/0253_auto_20210612_1256.py b/care/facility/migrations_old/0253_auto_20210612_1256.py similarity index 100% rename from care/facility/migrations/0253_auto_20210612_1256.py rename to care/facility/migrations_old/0253_auto_20210612_1256.py diff --git a/care/facility/migrations/0254_patientnotes.py b/care/facility/migrations_old/0254_patientnotes.py similarity index 100% rename from care/facility/migrations/0254_patientnotes.py rename to care/facility/migrations_old/0254_patientnotes.py diff --git a/care/facility/migrations/0255_asset_assetlocation_assettransaction_facilitydefaultassetlocation_userdefaultassetlocation.py b/care/facility/migrations_old/0255_asset_assetlocation_assettransaction_facilitydefaultassetlocation_userdefaultassetlocation.py similarity index 100% rename from care/facility/migrations/0255_asset_assetlocation_assettransaction_facilitydefaultassetlocation_userdefaultassetlocation.py rename to care/facility/migrations_old/0255_asset_assetlocation_assettransaction_facilitydefaultassetlocation_userdefaultassetlocation.py diff --git a/care/facility/migrations/0256_assettransaction_asset.py b/care/facility/migrations_old/0256_assettransaction_asset.py similarity index 100% rename from care/facility/migrations/0256_assettransaction_asset.py rename to care/facility/migrations_old/0256_assettransaction_asset.py diff --git a/care/facility/migrations/0257_auto_20210618_1642.py b/care/facility/migrations_old/0257_auto_20210618_1642.py similarity index 100% rename from care/facility/migrations/0257_auto_20210618_1642.py rename to care/facility/migrations_old/0257_auto_20210618_1642.py diff --git a/care/facility/migrations/0258_auto_20210623_1742.py b/care/facility/migrations_old/0258_auto_20210623_1742.py similarity index 100% rename from care/facility/migrations/0258_auto_20210623_1742.py rename to care/facility/migrations_old/0258_auto_20210623_1742.py diff --git a/care/facility/migrations/0259_patientexternaltest_patient_created.py b/care/facility/migrations_old/0259_patientexternaltest_patient_created.py similarity index 100% rename from care/facility/migrations/0259_patientexternaltest_patient_created.py rename to care/facility/migrations_old/0259_patientexternaltest_patient_created.py diff --git a/care/facility/migrations/0260_auto_20210710_1742.py b/care/facility/migrations_old/0260_auto_20210710_1742.py similarity index 100% rename from care/facility/migrations/0260_auto_20210710_1742.py rename to care/facility/migrations_old/0260_auto_20210710_1742.py diff --git a/care/facility/migrations/0261_auto_20210710_2305.py b/care/facility/migrations_old/0261_auto_20210710_2305.py similarity index 100% rename from care/facility/migrations/0261_auto_20210710_2305.py rename to care/facility/migrations_old/0261_auto_20210710_2305.py diff --git a/care/facility/migrations/0262_auto_20210711_0007.py b/care/facility/migrations_old/0262_auto_20210711_0007.py similarity index 100% rename from care/facility/migrations/0262_auto_20210711_0007.py rename to care/facility/migrations_old/0262_auto_20210711_0007.py diff --git a/care/facility/migrations/0263_auto_20210711_1716.py b/care/facility/migrations_old/0263_auto_20210711_1716.py similarity index 100% rename from care/facility/migrations/0263_auto_20210711_1716.py rename to care/facility/migrations_old/0263_auto_20210711_1716.py diff --git a/care/facility/migrations/0264_dailyround_in_prone_position.py b/care/facility/migrations_old/0264_dailyround_in_prone_position.py similarity index 100% rename from care/facility/migrations/0264_dailyround_in_prone_position.py rename to care/facility/migrations_old/0264_dailyround_in_prone_position.py diff --git a/care/facility/migrations/0265_auto_20210712_1133.py b/care/facility/migrations_old/0265_auto_20210712_1133.py similarity index 100% rename from care/facility/migrations/0265_auto_20210712_1133.py rename to care/facility/migrations_old/0265_auto_20210712_1133.py diff --git a/care/facility/migrations/0266_auto_20210717_2041.py b/care/facility/migrations_old/0266_auto_20210717_2041.py similarity index 100% rename from care/facility/migrations/0266_auto_20210717_2041.py rename to care/facility/migrations_old/0266_auto_20210717_2041.py diff --git a/care/facility/migrations/0267_dailyround_meta.py b/care/facility/migrations_old/0267_dailyround_meta.py similarity index 100% rename from care/facility/migrations/0267_dailyround_meta.py rename to care/facility/migrations_old/0267_dailyround_meta.py diff --git a/care/facility/migrations/0268_auto_20210729_1327.py b/care/facility/migrations_old/0268_auto_20210729_1327.py similarity index 100% rename from care/facility/migrations/0268_auto_20210729_1327.py rename to care/facility/migrations_old/0268_auto_20210729_1327.py diff --git a/care/facility/migrations/0268_patientconsultation_special_instruction.py b/care/facility/migrations_old/0268_patientconsultation_special_instruction.py similarity index 100% rename from care/facility/migrations/0268_patientconsultation_special_instruction.py rename to care/facility/migrations_old/0268_patientconsultation_special_instruction.py diff --git a/care/facility/migrations/0269_merge_20210815_1344.py b/care/facility/migrations_old/0269_merge_20210815_1344.py similarity index 100% rename from care/facility/migrations/0269_merge_20210815_1344.py rename to care/facility/migrations_old/0269_merge_20210815_1344.py diff --git a/care/facility/migrations/0270_auto_20210815_1356.py b/care/facility/migrations_old/0270_auto_20210815_1356.py similarity index 100% rename from care/facility/migrations/0270_auto_20210815_1356.py rename to care/facility/migrations_old/0270_auto_20210815_1356.py diff --git a/care/facility/migrations/0271_auto_20210815_1617.py b/care/facility/migrations_old/0271_auto_20210815_1617.py similarity index 100% rename from care/facility/migrations/0271_auto_20210815_1617.py rename to care/facility/migrations_old/0271_auto_20210815_1617.py diff --git a/care/facility/migrations/0272_auto_20210825_1248.py b/care/facility/migrations_old/0272_auto_20210825_1248.py similarity index 100% rename from care/facility/migrations/0272_auto_20210825_1248.py rename to care/facility/migrations_old/0272_auto_20210825_1248.py diff --git a/care/facility/migrations/0273_auto_20210825_1829.py b/care/facility/migrations_old/0273_auto_20210825_1829.py similarity index 100% rename from care/facility/migrations/0273_auto_20210825_1829.py rename to care/facility/migrations_old/0273_auto_20210825_1829.py diff --git a/care/facility/migrations/0274_auto_20210910_1647.py b/care/facility/migrations_old/0274_auto_20210910_1647.py similarity index 100% rename from care/facility/migrations/0274_auto_20210910_1647.py rename to care/facility/migrations_old/0274_auto_20210910_1647.py diff --git a/care/facility/migrations/0275_auto_20210917_1544.py b/care/facility/migrations_old/0275_auto_20210917_1544.py similarity index 100% rename from care/facility/migrations/0275_auto_20210917_1544.py rename to care/facility/migrations_old/0275_auto_20210917_1544.py diff --git a/care/facility/migrations/0275_auto_20210920_1811.py b/care/facility/migrations_old/0275_auto_20210920_1811.py similarity index 100% rename from care/facility/migrations/0275_auto_20210920_1811.py rename to care/facility/migrations_old/0275_auto_20210920_1811.py diff --git a/care/facility/migrations/0275_auto_20210927_2033.py b/care/facility/migrations_old/0275_auto_20210927_2033.py similarity index 100% rename from care/facility/migrations/0275_auto_20210927_2033.py rename to care/facility/migrations_old/0275_auto_20210927_2033.py diff --git a/care/facility/migrations/0276_auto_20210930_1451.py b/care/facility/migrations_old/0276_auto_20210930_1451.py similarity index 100% rename from care/facility/migrations/0276_auto_20210930_1451.py rename to care/facility/migrations_old/0276_auto_20210930_1451.py diff --git a/care/facility/migrations/0277_merge_20211011_2103.py b/care/facility/migrations_old/0277_merge_20211011_2103.py similarity index 100% rename from care/facility/migrations/0277_merge_20211011_2103.py rename to care/facility/migrations_old/0277_merge_20211011_2103.py diff --git a/care/facility/migrations/0278_asset_not_working_reason.py b/care/facility/migrations_old/0278_asset_not_working_reason.py similarity index 100% rename from care/facility/migrations/0278_asset_not_working_reason.py rename to care/facility/migrations_old/0278_asset_not_working_reason.py diff --git a/care/facility/migrations/0279_auto_20211122_1138.py b/care/facility/migrations_old/0279_auto_20211122_1138.py similarity index 100% rename from care/facility/migrations/0279_auto_20211122_1138.py rename to care/facility/migrations_old/0279_auto_20211122_1138.py diff --git a/care/facility/migrations/0280_auto_20211210_0038.py b/care/facility/migrations_old/0280_auto_20211210_0038.py similarity index 100% rename from care/facility/migrations/0280_auto_20211210_0038.py rename to care/facility/migrations_old/0280_auto_20211210_0038.py diff --git a/care/facility/migrations/0281_auto_20211214_1454.py b/care/facility/migrations_old/0281_auto_20211214_1454.py similarity index 100% rename from care/facility/migrations/0281_auto_20211214_1454.py rename to care/facility/migrations_old/0281_auto_20211214_1454.py diff --git a/care/facility/migrations/0282_dailyround_pain.py b/care/facility/migrations_old/0282_dailyround_pain.py similarity index 100% rename from care/facility/migrations/0282_dailyround_pain.py rename to care/facility/migrations_old/0282_dailyround_pain.py diff --git a/care/facility/migrations/0282_patientconsultation_last_daily_round.py b/care/facility/migrations_old/0282_patientconsultation_last_daily_round.py similarity index 100% rename from care/facility/migrations/0282_patientconsultation_last_daily_round.py rename to care/facility/migrations_old/0282_patientconsultation_last_daily_round.py diff --git a/care/facility/migrations/0283_merge_20220128_0315.py b/care/facility/migrations_old/0283_merge_20220128_0315.py similarity index 100% rename from care/facility/migrations/0283_merge_20220128_0315.py rename to care/facility/migrations_old/0283_merge_20220128_0315.py diff --git a/care/facility/migrations/0284_patientconsultation_hba1c.py b/care/facility/migrations_old/0284_patientconsultation_hba1c.py similarity index 100% rename from care/facility/migrations/0284_patientconsultation_hba1c.py rename to care/facility/migrations_old/0284_patientconsultation_hba1c.py diff --git a/care/facility/migrations/0285_asset_asset_class.py b/care/facility/migrations_old/0285_asset_asset_class.py similarity index 100% rename from care/facility/migrations/0285_asset_asset_class.py rename to care/facility/migrations_old/0285_asset_asset_class.py diff --git a/care/facility/migrations/0286_auto_20220316_2004.py b/care/facility/migrations_old/0286_auto_20220316_2004.py similarity index 100% rename from care/facility/migrations/0286_auto_20220316_2004.py rename to care/facility/migrations_old/0286_auto_20220316_2004.py diff --git a/care/facility/migrations/0287_asset_qr_code_id.py b/care/facility/migrations_old/0287_asset_qr_code_id.py similarity index 100% rename from care/facility/migrations/0287_asset_qr_code_id.py rename to care/facility/migrations_old/0287_asset_qr_code_id.py diff --git a/care/facility/migrations/0287_auto_20220415_1932.py b/care/facility/migrations_old/0287_auto_20220415_1932.py similarity index 100% rename from care/facility/migrations/0287_auto_20220415_1932.py rename to care/facility/migrations_old/0287_auto_20220415_1932.py diff --git a/care/facility/migrations/0288_auto_20220422_0206.py b/care/facility/migrations_old/0288_auto_20220422_0206.py similarity index 100% rename from care/facility/migrations/0288_auto_20220422_0206.py rename to care/facility/migrations_old/0288_auto_20220422_0206.py diff --git a/care/facility/migrations/0288_patientconsultation_current_bed.py b/care/facility/migrations_old/0288_patientconsultation_current_bed.py similarity index 100% rename from care/facility/migrations/0288_patientconsultation_current_bed.py rename to care/facility/migrations_old/0288_patientconsultation_current_bed.py diff --git a/care/facility/migrations/0289_merge_20220422_2220.py b/care/facility/migrations_old/0289_merge_20220422_2220.py similarity index 100% rename from care/facility/migrations/0289_merge_20220422_2220.py rename to care/facility/migrations_old/0289_merge_20220422_2220.py diff --git a/care/facility/migrations/0290_auto_20220426_2231.py b/care/facility/migrations_old/0290_auto_20220426_2231.py similarity index 100% rename from care/facility/migrations/0290_auto_20220426_2231.py rename to care/facility/migrations_old/0290_auto_20220426_2231.py diff --git a/care/facility/migrations/0291_facility_cover_image_url.py b/care/facility/migrations_old/0291_facility_cover_image_url.py similarity index 100% rename from care/facility/migrations/0291_facility_cover_image_url.py rename to care/facility/migrations_old/0291_facility_cover_image_url.py diff --git a/care/facility/migrations/0292_auto_20220430_1748.py b/care/facility/migrations_old/0292_auto_20220430_1748.py similarity index 100% rename from care/facility/migrations/0292_auto_20220430_1748.py rename to care/facility/migrations_old/0292_auto_20220430_1748.py diff --git a/care/facility/migrations/0293_auto_20220520_1941.py b/care/facility/migrations_old/0293_auto_20220520_1941.py similarity index 100% rename from care/facility/migrations/0293_auto_20220520_1941.py rename to care/facility/migrations_old/0293_auto_20220520_1941.py diff --git a/care/facility/migrations/0293_facility_middleware_address.py b/care/facility/migrations_old/0293_facility_middleware_address.py similarity index 100% rename from care/facility/migrations/0293_facility_middleware_address.py rename to care/facility/migrations_old/0293_facility_middleware_address.py diff --git a/care/facility/migrations/0294_auto_20220523_1419.py b/care/facility/migrations_old/0294_auto_20220523_1419.py similarity index 100% rename from care/facility/migrations/0294_auto_20220523_1419.py rename to care/facility/migrations_old/0294_auto_20220523_1419.py diff --git a/care/facility/migrations/0294_auto_20220526_0133.py b/care/facility/migrations_old/0294_auto_20220526_0133.py similarity index 100% rename from care/facility/migrations/0294_auto_20220526_0133.py rename to care/facility/migrations_old/0294_auto_20220526_0133.py diff --git a/care/facility/migrations/0295_merge_20220527_1430.py b/care/facility/migrations_old/0295_merge_20220527_1430.py similarity index 100% rename from care/facility/migrations/0295_merge_20220527_1430.py rename to care/facility/migrations_old/0295_merge_20220527_1430.py diff --git a/care/facility/migrations/0296_auto_20220527_1925.py b/care/facility/migrations_old/0296_auto_20220527_1925.py similarity index 100% rename from care/facility/migrations/0296_auto_20220527_1925.py rename to care/facility/migrations_old/0296_auto_20220527_1925.py diff --git a/care/facility/migrations/0297_auto_20220619_1821.py b/care/facility/migrations_old/0297_auto_20220619_1821.py similarity index 100% rename from care/facility/migrations/0297_auto_20220619_1821.py rename to care/facility/migrations_old/0297_auto_20220619_1821.py diff --git a/care/facility/migrations/0297_facility_location.py b/care/facility/migrations_old/0297_facility_location.py similarity index 96% rename from care/facility/migrations/0297_facility_location.py rename to care/facility/migrations_old/0297_facility_location.py index adc24dabe1..ab0f05d448 100644 --- a/care/facility/migrations/0297_facility_location.py +++ b/care/facility/migrations_old/0297_facility_location.py @@ -6,7 +6,7 @@ def populate_location(apps, schema_editor): try: from django.contrib.gis.geos import GEOSGeometry - except: + except Exception: return Facility = apps.get_model("facility", "Facility") facilities = Facility.objects.all() @@ -19,7 +19,7 @@ def populate_location(apps, schema_editor): facility.latitude = location.tuple[1] facility.location = None facility.save() - except Exception as e: + except Exception: pass diff --git a/care/facility/migrations/0298_auto_20220625_1627.py b/care/facility/migrations_old/0298_auto_20220625_1627.py similarity index 100% rename from care/facility/migrations/0298_auto_20220625_1627.py rename to care/facility/migrations_old/0298_auto_20220625_1627.py diff --git a/care/facility/migrations/0298_facility_features.py b/care/facility/migrations_old/0298_facility_features.py similarity index 100% rename from care/facility/migrations/0298_facility_features.py rename to care/facility/migrations_old/0298_facility_features.py diff --git a/care/facility/migrations/0299_merge_20220704_0225.py b/care/facility/migrations_old/0299_merge_20220704_0225.py similarity index 100% rename from care/facility/migrations/0299_merge_20220704_0225.py rename to care/facility/migrations_old/0299_merge_20220704_0225.py diff --git a/care/facility/migrations/0300_merge_20220707_2339.py b/care/facility/migrations_old/0300_merge_20220707_2339.py similarity index 100% rename from care/facility/migrations/0300_merge_20220707_2339.py rename to care/facility/migrations_old/0300_merge_20220707_2339.py diff --git a/care/facility/migrations/0301_auto_20220709_2051.py b/care/facility/migrations_old/0301_auto_20220709_2051.py similarity index 100% rename from care/facility/migrations/0301_auto_20220709_2051.py rename to care/facility/migrations_old/0301_auto_20220709_2051.py diff --git a/care/facility/migrations/0302_patientconsultation_prn_prescription.py b/care/facility/migrations_old/0302_patientconsultation_prn_prescription.py similarity index 100% rename from care/facility/migrations/0302_patientconsultation_prn_prescription.py rename to care/facility/migrations_old/0302_patientconsultation_prn_prescription.py diff --git a/care/facility/migrations/0303_patientconsultation_procedure.py b/care/facility/migrations_old/0303_patientconsultation_procedure.py similarity index 100% rename from care/facility/migrations/0303_patientconsultation_procedure.py rename to care/facility/migrations_old/0303_patientconsultation_procedure.py diff --git a/care/facility/migrations/0304_auto_20220726_1903.py b/care/facility/migrations_old/0304_auto_20220726_1903.py similarity index 100% rename from care/facility/migrations/0304_auto_20220726_1903.py rename to care/facility/migrations_old/0304_auto_20220726_1903.py diff --git a/care/facility/migrations/0305_auto_20220730_1956.py b/care/facility/migrations_old/0305_auto_20220730_1956.py similarity index 100% rename from care/facility/migrations/0305_auto_20220730_1956.py rename to care/facility/migrations_old/0305_auto_20220730_1956.py diff --git a/care/facility/migrations/0306_auto_20220803_1946.py b/care/facility/migrations_old/0306_auto_20220803_1946.py similarity index 100% rename from care/facility/migrations/0306_auto_20220803_1946.py rename to care/facility/migrations_old/0306_auto_20220803_1946.py diff --git a/care/facility/migrations/0307_auto_20220805_1933.py b/care/facility/migrations_old/0307_auto_20220805_1933.py similarity index 100% rename from care/facility/migrations/0307_auto_20220805_1933.py rename to care/facility/migrations_old/0307_auto_20220805_1933.py diff --git a/care/facility/migrations/0308_auto_20220805_2247.py b/care/facility/migrations_old/0308_auto_20220805_2247.py similarity index 100% rename from care/facility/migrations/0308_auto_20220805_2247.py rename to care/facility/migrations_old/0308_auto_20220805_2247.py diff --git a/care/facility/migrations/0309_auto_20220818_1949.py b/care/facility/migrations_old/0309_auto_20220818_1949.py similarity index 100% rename from care/facility/migrations/0309_auto_20220818_1949.py rename to care/facility/migrations_old/0309_auto_20220818_1949.py diff --git a/care/facility/migrations/0309_auto_20220820_1541.py b/care/facility/migrations_old/0309_auto_20220820_1541.py similarity index 100% rename from care/facility/migrations/0309_auto_20220820_1541.py rename to care/facility/migrations_old/0309_auto_20220820_1541.py diff --git a/care/facility/migrations/0310_merge_20220820_2047.py b/care/facility/migrations_old/0310_merge_20220820_2047.py similarity index 100% rename from care/facility/migrations/0310_merge_20220820_2047.py rename to care/facility/migrations_old/0310_merge_20220820_2047.py diff --git a/care/facility/migrations/0311_auto_20220824_1757.py b/care/facility/migrations_old/0311_auto_20220824_1757.py similarity index 100% rename from care/facility/migrations/0311_auto_20220824_1757.py rename to care/facility/migrations_old/0311_auto_20220824_1757.py diff --git a/care/facility/migrations/0312_patientconsultation_investigation.py b/care/facility/migrations_old/0312_patientconsultation_investigation.py similarity index 100% rename from care/facility/migrations/0312_patientconsultation_investigation.py rename to care/facility/migrations_old/0312_patientconsultation_investigation.py diff --git a/care/facility/migrations/0313_auto_20220901_2213.py b/care/facility/migrations_old/0313_auto_20220901_2213.py similarity index 100% rename from care/facility/migrations/0313_auto_20220901_2213.py rename to care/facility/migrations_old/0313_auto_20220901_2213.py diff --git a/care/facility/migrations/0314_patientconsultation_icd11_diagnoses.py b/care/facility/migrations_old/0314_patientconsultation_icd11_diagnoses.py similarity index 100% rename from care/facility/migrations/0314_patientconsultation_icd11_diagnoses.py rename to care/facility/migrations_old/0314_patientconsultation_icd11_diagnoses.py diff --git a/care/facility/migrations/0315_auto_20220908_1027.py b/care/facility/migrations_old/0315_auto_20220908_1027.py similarity index 100% rename from care/facility/migrations/0315_auto_20220908_1027.py rename to care/facility/migrations_old/0315_auto_20220908_1027.py diff --git a/care/facility/migrations/0315_auto_20220909_0925.py b/care/facility/migrations_old/0315_auto_20220909_0925.py similarity index 100% rename from care/facility/migrations/0315_auto_20220909_0925.py rename to care/facility/migrations_old/0315_auto_20220909_0925.py diff --git a/care/facility/migrations/0315_auto_20220909_2322.py b/care/facility/migrations_old/0315_auto_20220909_2322.py similarity index 100% rename from care/facility/migrations/0315_auto_20220909_2322.py rename to care/facility/migrations_old/0315_auto_20220909_2322.py diff --git a/care/facility/migrations/0315_patientconsultation_icd11_provisional_diagnoses.py b/care/facility/migrations_old/0315_patientconsultation_icd11_provisional_diagnoses.py similarity index 100% rename from care/facility/migrations/0315_patientconsultation_icd11_provisional_diagnoses.py rename to care/facility/migrations_old/0315_patientconsultation_icd11_provisional_diagnoses.py diff --git a/care/facility/migrations/0316_auto_20220908_1112.py b/care/facility/migrations_old/0316_auto_20220908_1112.py similarity index 100% rename from care/facility/migrations/0316_auto_20220908_1112.py rename to care/facility/migrations_old/0316_auto_20220908_1112.py diff --git a/care/facility/migrations/0316_auto_20220909_2331.py b/care/facility/migrations_old/0316_auto_20220909_2331.py similarity index 100% rename from care/facility/migrations/0316_auto_20220909_2331.py rename to care/facility/migrations_old/0316_auto_20220909_2331.py diff --git a/care/facility/migrations/0317_merge_20220915_2209.py b/care/facility/migrations_old/0317_merge_20220915_2209.py similarity index 100% rename from care/facility/migrations/0317_merge_20220915_2209.py rename to care/facility/migrations_old/0317_merge_20220915_2209.py diff --git a/care/facility/migrations/0318_merge_20220917_2113.py b/care/facility/migrations_old/0318_merge_20220917_2113.py similarity index 100% rename from care/facility/migrations/0318_merge_20220917_2113.py rename to care/facility/migrations_old/0318_merge_20220917_2113.py diff --git a/care/facility/migrations/0318_merge_20220918_1241.py b/care/facility/migrations_old/0318_merge_20220918_1241.py similarity index 100% rename from care/facility/migrations/0318_merge_20220918_1241.py rename to care/facility/migrations_old/0318_merge_20220918_1241.py diff --git a/care/facility/migrations/0319_dailyround_medicine_administration.py b/care/facility/migrations_old/0319_dailyround_medicine_administration.py similarity index 100% rename from care/facility/migrations/0319_dailyround_medicine_administration.py rename to care/facility/migrations_old/0319_dailyround_medicine_administration.py diff --git a/care/facility/migrations/0319_file_upload_completed.py b/care/facility/migrations_old/0319_file_upload_completed.py similarity index 100% rename from care/facility/migrations/0319_file_upload_completed.py rename to care/facility/migrations_old/0319_file_upload_completed.py diff --git a/care/facility/migrations/0320_merge_20220920_2114.py b/care/facility/migrations_old/0320_merge_20220920_2114.py similarity index 100% rename from care/facility/migrations/0320_merge_20220920_2114.py rename to care/facility/migrations_old/0320_merge_20220920_2114.py diff --git a/care/facility/migrations/0321_merge_20220921_2255.py b/care/facility/migrations_old/0321_merge_20220921_2255.py similarity index 100% rename from care/facility/migrations/0321_merge_20220921_2255.py rename to care/facility/migrations_old/0321_merge_20220921_2255.py diff --git a/care/facility/migrations/0322_fileupload_is_archived.py b/care/facility/migrations_old/0322_fileupload_is_archived.py similarity index 100% rename from care/facility/migrations/0322_fileupload_is_archived.py rename to care/facility/migrations_old/0322_fileupload_is_archived.py diff --git a/care/facility/migrations/0322_patientconsultation_review_interval.py b/care/facility/migrations_old/0322_patientconsultation_review_interval.py similarity index 100% rename from care/facility/migrations/0322_patientconsultation_review_interval.py rename to care/facility/migrations_old/0322_patientconsultation_review_interval.py diff --git a/care/facility/migrations/0323_fileupload_archive_reason.py b/care/facility/migrations_old/0323_fileupload_archive_reason.py similarity index 100% rename from care/facility/migrations/0323_fileupload_archive_reason.py rename to care/facility/migrations_old/0323_fileupload_archive_reason.py diff --git a/care/facility/migrations/0324_merge_20221013_0053.py b/care/facility/migrations_old/0324_merge_20221013_0053.py similarity index 100% rename from care/facility/migrations/0324_merge_20221013_0053.py rename to care/facility/migrations_old/0324_merge_20221013_0053.py diff --git a/care/facility/migrations/0325_merge_20221015_2136.py b/care/facility/migrations_old/0325_merge_20221015_2136.py similarity index 100% rename from care/facility/migrations/0325_merge_20221015_2136.py rename to care/facility/migrations_old/0325_merge_20221015_2136.py diff --git a/care/facility/migrations/0326_auto_20221018_1526.py b/care/facility/migrations_old/0326_auto_20221018_1526.py similarity index 100% rename from care/facility/migrations/0326_auto_20221018_1526.py rename to care/facility/migrations_old/0326_auto_20221018_1526.py diff --git a/care/facility/migrations/0327_auto_20221122_1750.py b/care/facility/migrations_old/0327_auto_20221122_1750.py similarity index 100% rename from care/facility/migrations/0327_auto_20221122_1750.py rename to care/facility/migrations_old/0327_auto_20221122_1750.py diff --git a/care/facility/migrations/0327_fileupload_archived_by.py b/care/facility/migrations_old/0327_fileupload_archived_by.py similarity index 100% rename from care/facility/migrations/0327_fileupload_archived_by.py rename to care/facility/migrations_old/0327_fileupload_archived_by.py diff --git a/care/facility/migrations/0328_merge_20221208_1110.py b/care/facility/migrations_old/0328_merge_20221208_1110.py similarity index 100% rename from care/facility/migrations/0328_merge_20221208_1110.py rename to care/facility/migrations_old/0328_merge_20221208_1110.py diff --git a/care/facility/migrations/0329_auto_20221223_1152.py b/care/facility/migrations_old/0329_auto_20221223_1152.py similarity index 100% rename from care/facility/migrations/0329_auto_20221223_1152.py rename to care/facility/migrations_old/0329_auto_20221223_1152.py diff --git a/care/facility/migrations/0330_auto_20221223_1952.py b/care/facility/migrations_old/0330_auto_20221223_1952.py similarity index 100% rename from care/facility/migrations/0330_auto_20221223_1952.py rename to care/facility/migrations_old/0330_auto_20221223_1952.py diff --git a/care/facility/migrations/0331_auto_20221224_1531.py b/care/facility/migrations_old/0331_auto_20221224_1531.py similarity index 100% rename from care/facility/migrations/0331_auto_20221224_1531.py rename to care/facility/migrations_old/0331_auto_20221224_1531.py diff --git a/care/facility/migrations/0332_auto_20230110_2114.py b/care/facility/migrations_old/0332_auto_20230110_2114.py similarity index 100% rename from care/facility/migrations/0332_auto_20230110_2114.py rename to care/facility/migrations_old/0332_auto_20230110_2114.py diff --git a/care/facility/migrations/0332_patientconsultation_consultation_status.py b/care/facility/migrations_old/0332_patientconsultation_consultation_status.py similarity index 100% rename from care/facility/migrations/0332_patientconsultation_consultation_status.py rename to care/facility/migrations_old/0332_patientconsultation_consultation_status.py diff --git a/care/facility/migrations/0333_auto_20230112_2233.py b/care/facility/migrations_old/0333_auto_20230112_2233.py similarity index 95% rename from care/facility/migrations/0333_auto_20230112_2233.py rename to care/facility/migrations_old/0333_auto_20230112_2233.py index 5883e58166..dcd1c47acd 100644 --- a/care/facility/migrations/0333_auto_20230112_2233.py +++ b/care/facility/migrations_old/0333_auto_20230112_2233.py @@ -1,6 +1,5 @@ # Generated by Django 2.2.11 on 2023-01-12 17:03 -import django.db.models.deletion from django.conf import settings from django.db import migrations, models diff --git a/care/facility/migrations/0334_merge_20230113_1507.py b/care/facility/migrations_old/0334_merge_20230113_1507.py similarity index 100% rename from care/facility/migrations/0334_merge_20230113_1507.py rename to care/facility/migrations_old/0334_merge_20230113_1507.py diff --git a/care/facility/migrations/0335_auto_20230207_1914.py b/care/facility/migrations_old/0335_auto_20230207_1914.py similarity index 100% rename from care/facility/migrations/0335_auto_20230207_1914.py rename to care/facility/migrations_old/0335_auto_20230207_1914.py diff --git a/care/facility/migrations/0336_auto_20230222_1602.py b/care/facility/migrations_old/0336_auto_20230222_1602.py similarity index 100% rename from care/facility/migrations/0336_auto_20230222_1602.py rename to care/facility/migrations_old/0336_auto_20230222_1602.py diff --git a/care/facility/migrations/0336_patientconsultation_op_no.py b/care/facility/migrations_old/0336_patientconsultation_op_no.py similarity index 100% rename from care/facility/migrations/0336_patientconsultation_op_no.py rename to care/facility/migrations_old/0336_patientconsultation_op_no.py diff --git a/care/facility/migrations/0337_metaicd11diagnosis.py b/care/facility/migrations_old/0337_metaicd11diagnosis.py similarity index 100% rename from care/facility/migrations/0337_metaicd11diagnosis.py rename to care/facility/migrations_old/0337_metaicd11diagnosis.py diff --git a/care/facility/migrations/0337_patientconsultation_referred_to_external.py b/care/facility/migrations_old/0337_patientconsultation_referred_to_external.py similarity index 100% rename from care/facility/migrations/0337_patientconsultation_referred_to_external.py rename to care/facility/migrations_old/0337_patientconsultation_referred_to_external.py diff --git a/care/facility/migrations/0338_auto_20230323_1249.py b/care/facility/migrations_old/0338_auto_20230323_1249.py similarity index 100% rename from care/facility/migrations/0338_auto_20230323_1249.py rename to care/facility/migrations_old/0338_auto_20230323_1249.py diff --git a/care/facility/migrations/0339_merge_20230406_1408.py b/care/facility/migrations_old/0339_merge_20230406_1408.py similarity index 100% rename from care/facility/migrations/0339_merge_20230406_1408.py rename to care/facility/migrations_old/0339_merge_20230406_1408.py diff --git a/care/facility/migrations/0340_auto_20230406_1409.py b/care/facility/migrations_old/0340_auto_20230406_1409.py similarity index 100% rename from care/facility/migrations/0340_auto_20230406_1409.py rename to care/facility/migrations_old/0340_auto_20230406_1409.py diff --git a/care/facility/migrations/0341_auto_20230407_0346.py b/care/facility/migrations_old/0341_auto_20230407_0346.py similarity index 100% rename from care/facility/migrations/0341_auto_20230407_0346.py rename to care/facility/migrations_old/0341_auto_20230407_0346.py diff --git a/care/facility/migrations/0342_auto_20230407_1424.py b/care/facility/migrations_old/0342_auto_20230407_1424.py similarity index 100% rename from care/facility/migrations/0342_auto_20230407_1424.py rename to care/facility/migrations_old/0342_auto_20230407_1424.py diff --git a/care/facility/migrations/0343_auto_20230407_1850.py b/care/facility/migrations_old/0343_auto_20230407_1850.py similarity index 100% rename from care/facility/migrations/0343_auto_20230407_1850.py rename to care/facility/migrations_old/0343_auto_20230407_1850.py diff --git a/care/facility/migrations/0344_auto_20230414_2040.py b/care/facility/migrations_old/0344_auto_20230414_2040.py similarity index 100% rename from care/facility/migrations/0344_auto_20230414_2040.py rename to care/facility/migrations_old/0344_auto_20230414_2040.py diff --git a/care/facility/migrations/0344_shiftingrequest_assigned_facility_external.py b/care/facility/migrations_old/0344_shiftingrequest_assigned_facility_external.py similarity index 100% rename from care/facility/migrations/0344_shiftingrequest_assigned_facility_external.py rename to care/facility/migrations_old/0344_shiftingrequest_assigned_facility_external.py diff --git a/care/facility/migrations/0345_auto_20230414_2046.py b/care/facility/migrations_old/0345_auto_20230414_2046.py similarity index 100% rename from care/facility/migrations/0345_auto_20230414_2046.py rename to care/facility/migrations_old/0345_auto_20230414_2046.py diff --git a/care/facility/migrations/0346_merge_20230419_0952.py b/care/facility/migrations_old/0346_merge_20230419_0952.py similarity index 100% rename from care/facility/migrations/0346_merge_20230419_0952.py rename to care/facility/migrations_old/0346_merge_20230419_0952.py diff --git a/care/facility/migrations/0347_auto_20230421_1357.py b/care/facility/migrations_old/0347_auto_20230421_1357.py similarity index 100% rename from care/facility/migrations/0347_auto_20230421_1357.py rename to care/facility/migrations_old/0347_auto_20230421_1357.py diff --git a/care/facility/migrations/0348_merge_20230421_1917.py b/care/facility/migrations_old/0348_merge_20230421_1917.py similarity index 100% rename from care/facility/migrations/0348_merge_20230421_1917.py rename to care/facility/migrations_old/0348_merge_20230421_1917.py diff --git a/care/facility/migrations/0349_auto_20230422_2058.py b/care/facility/migrations_old/0349_auto_20230422_2058.py similarity index 100% rename from care/facility/migrations/0349_auto_20230422_2058.py rename to care/facility/migrations_old/0349_auto_20230422_2058.py diff --git a/care/facility/migrations/0350_auto_20230422_2114.py b/care/facility/migrations_old/0350_auto_20230422_2114.py similarity index 100% rename from care/facility/migrations/0350_auto_20230422_2114.py rename to care/facility/migrations_old/0350_auto_20230422_2114.py diff --git a/care/facility/migrations/0351_auto_20230424_1227.py b/care/facility/migrations_old/0351_auto_20230424_1227.py similarity index 100% rename from care/facility/migrations/0351_auto_20230424_1227.py rename to care/facility/migrations_old/0351_auto_20230424_1227.py diff --git a/care/facility/migrations/0352_auto_20230428_1539.py b/care/facility/migrations_old/0352_auto_20230428_1539.py similarity index 86% rename from care/facility/migrations/0352_auto_20230428_1539.py rename to care/facility/migrations_old/0352_auto_20230428_1539.py index 3a91dae64e..f862ae972f 100644 --- a/care/facility/migrations/0352_auto_20230428_1539.py +++ b/care/facility/migrations_old/0352_auto_20230428_1539.py @@ -1,4 +1,4 @@ -from django.db import migrations, models +from django.db import migrations class Migration(migrations.Migration): diff --git a/care/facility/migrations/0353_auto_20230429_2026.py b/care/facility/migrations_old/0353_auto_20230429_2026.py similarity index 100% rename from care/facility/migrations/0353_auto_20230429_2026.py rename to care/facility/migrations_old/0353_auto_20230429_2026.py diff --git a/care/facility/migrations/0354_auto_20230519_1501.py b/care/facility/migrations_old/0354_auto_20230519_1501.py similarity index 100% rename from care/facility/migrations/0354_auto_20230519_1501.py rename to care/facility/migrations_old/0354_auto_20230519_1501.py diff --git a/care/facility/migrations/0355_auto_20230429_2027.py b/care/facility/migrations_old/0355_auto_20230429_2027.py similarity index 99% rename from care/facility/migrations/0355_auto_20230429_2027.py rename to care/facility/migrations_old/0355_auto_20230429_2027.py index b93d00b103..c29a303700 100644 --- a/care/facility/migrations/0355_auto_20230429_2027.py +++ b/care/facility/migrations_old/0355_auto_20230429_2027.py @@ -20,7 +20,7 @@ def clean_integer(value): try: return round(float(value)) or None - except: + except Exception: return None diff --git a/care/facility/migrations/0356_auto_20230512_1122.py b/care/facility/migrations_old/0356_auto_20230512_1122.py similarity index 100% rename from care/facility/migrations/0356_auto_20230512_1122.py rename to care/facility/migrations_old/0356_auto_20230512_1122.py diff --git a/care/facility/migrations/0357_auto_20230523_1304.py b/care/facility/migrations_old/0357_auto_20230523_1304.py similarity index 100% rename from care/facility/migrations/0357_auto_20230523_1304.py rename to care/facility/migrations_old/0357_auto_20230523_1304.py diff --git a/care/facility/migrations/0358_auto_20230524_1853.py b/care/facility/migrations_old/0358_auto_20230524_1853.py similarity index 100% rename from care/facility/migrations/0358_auto_20230524_1853.py rename to care/facility/migrations_old/0358_auto_20230524_1853.py diff --git a/care/facility/migrations/0359_auto_20230529_1907.py b/care/facility/migrations_old/0359_auto_20230529_1907.py similarity index 100% rename from care/facility/migrations/0359_auto_20230529_1907.py rename to care/facility/migrations_old/0359_auto_20230529_1907.py diff --git a/care/facility/migrations/0360_auto_20230608_1750.py b/care/facility/migrations_old/0360_auto_20230608_1750.py similarity index 100% rename from care/facility/migrations/0360_auto_20230608_1750.py rename to care/facility/migrations_old/0360_auto_20230608_1750.py diff --git a/care/facility/migrations_old/__init__.py b/care/facility/migrations_old/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/care/hcx/migrations/0001_initial_squashed.py b/care/hcx/migrations/0001_initial_squashed.py new file mode 100644 index 0000000000..0ed09f9623 --- /dev/null +++ b/care/hcx/migrations/0001_initial_squashed.py @@ -0,0 +1,309 @@ +# Generated by Django 2.2.11 on 2023-06-13 10:52 + +import uuid + +import django.contrib.postgres.fields.jsonb +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + +import care.utils.models.validators + + +class Migration(migrations.Migration): + initial = True + + replaces = [ + ("hcx", "0001_initial"), + ("hcx", "0002_claim"), + ("hcx", "0003_auto_20230217_1901"), + ("hcx", "0004_auto_20230222_2012"), + ("hcx", "0005_auto_20230222_2217"), + ("hcx", "0006_auto_20230323_1208"), + ] + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("facility", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Policy", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("subscriber_id", models.TextField(blank=True, null=True)), + ("policy_id", models.TextField(blank=True, null=True)), + ("insurer_id", models.TextField(blank=True, null=True)), + ("insurer_name", models.TextField(blank=True, null=True)), + ( + "status", + models.CharField( + blank=True, + choices=[ + ("active", "Active"), + ("cancelled", "Cancelled"), + ("draft", "Draft"), + ("entered-in-error", "Entered in Error"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ( + "priority", + models.CharField( + choices=[ + ("stat", "Immediate"), + ("normal", "Normal"), + ("deferred", "Deferred"), + ], + default="normal", + max_length=20, + ), + ), + ( + "purpose", + models.CharField( + blank=True, + choices=[ + ("auth-requirements", "Auth Requirements"), + ("benefits", "Benefits"), + ("discovery", "Discovery"), + ("validation", "Validation"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ( + "outcome", + models.CharField( + blank=True, + choices=[ + ("queued", "Queued"), + ("complete", "Processing Complete"), + ("error", "Error"), + ("partial", "Partial Processing"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ("error_text", models.TextField(blank=True, null=True)), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "last_modified_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="policy_last_modified_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "patient", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.PatientRegistration", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Claim", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "items", + django.contrib.postgres.fields.jsonb.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "category": {"type": "string"}, + "id": {"type": "string"}, + "name": {"type": "string"}, + "price": {"type": "number"}, + }, + "required": ["id", "name", "price"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + ("total_claim_amount", models.FloatField(blank=True, null=True)), + ("total_amount_approved", models.FloatField(blank=True, null=True)), + ( + "use", + models.CharField( + blank=True, + choices=[ + ("claim", "Claim"), + ("preauthorization", "Pre-Authorization"), + ("predetermination", "Pre-Determination"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ( + "status", + models.CharField( + blank=True, + choices=[ + ("active", "Active"), + ("cancelled", "Cancelled"), + ("draft", "Draft"), + ("entered-in-error", "Entered in Error"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ( + "priority", + models.CharField( + choices=[ + ("stat", "Immediate"), + ("normal", "Normal"), + ("deferred", "Deferred"), + ], + default="normal", + max_length=20, + ), + ), + ( + "type", + models.CharField( + blank=True, + choices=[ + ("institutional", "Institutional"), + ("oral", "Oral"), + ("pharmacy", "Pharmacy"), + ("professional", "Professional"), + ("vision", "Vision"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ( + "outcome", + models.CharField( + blank=True, + choices=[ + ("queued", "Queued"), + ("complete", "Processing Complete"), + ("error", "Error"), + ("partial", "Partial Processing"), + ], + default=None, + max_length=20, + null=True, + ), + ), + ("error_text", models.TextField(blank=True, null=True)), + ( + "consultation", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="facility.PatientConsultation", + ), + ), + ( + "created_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "last_modified_by", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="claim_last_modified_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "policy", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="hcx.Policy" + ), + ), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/care/hcx/migrations/0001_initial.py b/care/hcx/migrations_old/0001_initial.py similarity index 100% rename from care/hcx/migrations/0001_initial.py rename to care/hcx/migrations_old/0001_initial.py diff --git a/care/hcx/migrations/0002_claim.py b/care/hcx/migrations_old/0002_claim.py similarity index 100% rename from care/hcx/migrations/0002_claim.py rename to care/hcx/migrations_old/0002_claim.py diff --git a/care/hcx/migrations/0003_auto_20230217_1901.py b/care/hcx/migrations_old/0003_auto_20230217_1901.py similarity index 100% rename from care/hcx/migrations/0003_auto_20230217_1901.py rename to care/hcx/migrations_old/0003_auto_20230217_1901.py diff --git a/care/hcx/migrations/0004_auto_20230222_2012.py b/care/hcx/migrations_old/0004_auto_20230222_2012.py similarity index 100% rename from care/hcx/migrations/0004_auto_20230222_2012.py rename to care/hcx/migrations_old/0004_auto_20230222_2012.py diff --git a/care/hcx/migrations/0005_auto_20230222_2217.py b/care/hcx/migrations_old/0005_auto_20230222_2217.py similarity index 100% rename from care/hcx/migrations/0005_auto_20230222_2217.py rename to care/hcx/migrations_old/0005_auto_20230222_2217.py diff --git a/care/hcx/migrations/0006_auto_20230323_1208.py b/care/hcx/migrations_old/0006_auto_20230323_1208.py similarity index 100% rename from care/hcx/migrations/0006_auto_20230323_1208.py rename to care/hcx/migrations_old/0006_auto_20230323_1208.py diff --git a/care/hcx/migrations_old/__init__.py b/care/hcx/migrations_old/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/care/users/migrations/0001_initial_squashed.py b/care/users/migrations/0001_initial_squashed.py new file mode 100644 index 0000000000..163fede411 --- /dev/null +++ b/care/users/migrations/0001_initial_squashed.py @@ -0,0 +1,525 @@ +# Generated by Django 2.2.11 on 2023-06-13 10:51 + +import uuid + +import django.core.validators +import django.db.models.deletion +import django.utils.timezone +import partial_index +from django.conf import settings +from django.db import migrations, models + +import care.users.models + + +class Migration(migrations.Migration): + initial = True + replaces = [ + ("users", "0001_initial"), + ("users", "0002_auto_20200319_0634"), + ("users", "0003_user_verified"), + ("users", "0004_auto_20200321_0556"), + ("users", "0005_auto_20200321_0601"), + ("users", "0006_user_deleted"), + ("users", "0007_auto_20200321_2029"), + ("users", "0008_auto_20200321_2035"), + ("users", "0009_auto_20200325_1908"), + ("users", "0010_populate_district"), + ("users", "0011_map_users_to_district"), + ("users", "0012_auto_20200326_0342"), + ("users", "0013_auto_20200327_0437"), + ("users", "0014_restart_sequence_districts"), + ("users", "0012_auto_20200326_1752"), + ("users", "0013_auto_20200326_2021"), + ("users", "0015_merge_20200327_1215"), + ("users", "0016_auto_20200327_1954"), + ("users", "0017_auto_20200328_2256"), + ("users", "0018_auto_20200328_1853"), + ("users", "0019_auto_20200328_2226"), + ("users", "0020_auto_20200401_0930"), + ("users", "0021_make_kerala_everyones_state"), + ("users", "0022_auto_verify_users_with_facility"), + ("users", "0023_auto_20200413_1301"), + ("users", "0024_auto_20200801_1844"), + ("users", "0025_auto_20200914_2027"), + ("users", "0026_auto_20200914_2034"), + ("users", "0027_auto_20200914_2052"), + ("users", "0028_auto_20200916_0008"), + ("users", "0029_ward"), + ("users", "0030_auto_20200921_1659"), + ("users", "0031_auto_20200927_1325"), + ("users", "0032_user_ward"), + ("users", "0033_auto_20201011_1908"), + ("users", "0034_auto_20201122_2013"), + ("users", "0035_auto_20210511_2105"), + ("users", "0036_auto_20210515_2048"), + ("users", "0037_auto_20210519_1826"), + ("users", "0038_user_alt_phone_number"), + ("users", "0039_auto_20210616_1634"), + ("users", "0040_auto_20210616_1821"), + ("users", "0041_user_asset"), + ("users", "0042_user_created_by"), + ("users", "0043_auto_20220624_1119"), + ("users", "0044_user_home_facility"), + ("users", "0045_auto_20230110_1120"), + ("users", "0046_auto_20230204_1733"), + ("users", "0047_user_external_id"), + ("users", "0048_auto_20230609_1411"), + ("users", "0049_auto_20230609_1413"), + ] + + dependencies = [ + ("auth", "0011_update_proxy_permissions"), + ] + + operations = [ + migrations.CreateModel( + name="User", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=30, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "email", + models.EmailField( + blank=True, max_length=254, verbose_name="email address" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "username", + models.CharField( + error_messages={ + "unique": "A user with that username already exists." + }, + help_text="150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[care.users.models.UsernameValidator()], + verbose_name="username", + ), + ), + ( + "user_type", + models.IntegerField( + choices=[ + (2, "Transportation"), + (3, "Pharmacist"), + (5, "Volunteer"), + (9, "StaffReadOnly"), + (10, "Staff"), + (15, "Doctor"), + (20, "Reserved"), + (21, "WardAdmin"), + (23, "LocalBodyAdmin"), + (25, "DistrictLabAdmin"), + (29, "DistrictReadOnlyAdmin"), + (30, "DistrictAdmin"), + (35, "StateLabAdmin"), + (39, "StateReadOnlyAdmin"), + (40, "StateAdmin"), + ] + ), + ), + ( + "phone_number", + models.CharField( + max_length=14, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ( + "alt_phone_number", + models.CharField( + blank=True, + default=None, + max_length=14, + null=True, + validators=[ + django.core.validators.RegexValidator( + code="invalid_mobile", + message="Please Enter 10/11 digit mobile number or landline as 0", + regex="^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$", + ) + ], + ), + ), + ( + "gender", + models.IntegerField( + choices=[(1, "Male"), (2, "Female"), (3, "Non-binary")] + ), + ), + ( + "age", + models.IntegerField( + validators=[ + django.core.validators.MinValueValidator(1), + django.core.validators.MaxValueValidator(100), + ] + ), + ), + ("doctor_qualification", models.TextField(null=True)), + ( + "doctor_experience_commenced_on", + models.DateField(default=None, null=True), + ), + ( + "doctor_medical_council_registration", + models.CharField(default=None, max_length=255, null=True), + ), + ("verified", models.BooleanField(default=False)), + ("deleted", models.BooleanField(default=False)), + ("pf_endpoint", models.TextField(default=None, null=True)), + ("pf_p256dh", models.TextField(default=None, null=True)), + ("pf_auth", models.TextField(default=None, null=True)), + ( + "created_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="users_created", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, + }, + managers=[ + ("objects", care.users.models.CustomUserManager()), + ], + ), + migrations.CreateModel( + name="District", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="LocalBody", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ( + "body_type", + models.IntegerField( + choices=[ + (1, "Grama Panchayath"), + (2, "Block Panchayath"), + (3, "District Panchayath"), + (4, "Nagar Panchayath"), + (10, "Municipality"), + (20, "Corporation"), + (50, "Others"), + ] + ), + ), + ( + "localbody_code", + models.CharField(blank=True, max_length=20, null=True), + ), + ( + "district", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="users.District" + ), + ), + ], + options={ + "verbose_name": "Local Body", + "verbose_name_plural": "Local Bodies", + }, + ), + migrations.CreateModel( + name="Skill", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ("name", models.CharField(max_length=255, unique=True)), + ("description", models.TextField(blank=True, default="", null=True)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="State", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Ward", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("number", models.IntegerField()), + ( + "local_body", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="users.LocalBody", + ), + ), + ], + options={ + "unique_together": {("local_body", "name", "number")}, + }, + ), + migrations.CreateModel( + name="UserSkill", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "external_id", + models.UUIDField(db_index=True, default=uuid.uuid4, unique=True), + ), + ( + "created_date", + models.DateTimeField(auto_now_add=True, db_index=True, null=True), + ), + ( + "modified_date", + models.DateTimeField(auto_now=True, db_index=True, null=True), + ), + ("deleted", models.BooleanField(db_index=True, default=False)), + ( + "skill", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="users.Skill", + ), + ), + ( + "user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.AddField( + model_name="district", + name="state", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="users.State" + ), + ), + migrations.AddField( + model_name="user", + name="district", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.District", + ), + ), + migrations.AddField( + model_name="user", + name="groups", + field=models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.Group", + verbose_name="groups", + ), + ), + migrations.AddField( + model_name="user", + name="local_body", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.LocalBody", + ), + ), + migrations.AddField( + model_name="user", + name="skills", + field=models.ManyToManyField(through="users.UserSkill", to="users.Skill"), + ), + migrations.AddField( + model_name="user", + name="state", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.State", + ), + ), + migrations.AddField( + model_name="user", + name="user_permissions", + field=models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.Permission", + verbose_name="user permissions", + ), + ), + migrations.AddField( + model_name="user", + name="ward", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="users.Ward", + ), + ), + migrations.AddIndex( + model_name="userskill", + index=partial_index.PartialIndex( + fields=["skill", "user"], + name="users_users_skill_i_6ebc32_partial", + unique=True, + where=partial_index.PQ(deleted=False), + ), + ), + migrations.AlterUniqueTogether( + name="localbody", + unique_together={("district", "body_type", "name")}, + ), + ] diff --git a/care/users/migrations/0002_auto_20230613_1622.py b/care/users/migrations/0002_auto_20230613_1622.py new file mode 100644 index 0000000000..253fe74271 --- /dev/null +++ b/care/users/migrations/0002_auto_20230613_1622.py @@ -0,0 +1,90 @@ +# Generated by Django 2.2.11 on 2023-06-13 10:52 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + replaces = [ + ("users", "0002_auto_20200319_0634"), + ("users", "0003_user_verified"), + ("users", "0004_auto_20200321_0556"), + ("users", "0005_auto_20200321_0601"), + ("users", "0006_user_deleted"), + ("users", "0007_auto_20200321_2029"), + ("users", "0008_auto_20200321_2035"), + ("users", "0009_auto_20200325_1908"), + ("users", "0010_populate_district"), + ("users", "0011_map_users_to_district"), + ("users", "0012_auto_20200326_0342"), + ("users", "0013_auto_20200327_0437"), + ("users", "0014_restart_sequence_districts"), + ("users", "0012_auto_20200326_1752"), + ("users", "0013_auto_20200326_2021"), + ("users", "0015_merge_20200327_1215"), + ("users", "0016_auto_20200327_1954"), + ("users", "0017_auto_20200328_2256"), + ("users", "0018_auto_20200328_1853"), + ("users", "0019_auto_20200328_2226"), + ("users", "0020_auto_20200401_0930"), + ("users", "0021_make_kerala_everyones_state"), + ("users", "0022_auto_verify_users_with_facility"), + ("users", "0023_auto_20200413_1301"), + ("users", "0024_auto_20200801_1844"), + ("users", "0025_auto_20200914_2027"), + ("users", "0026_auto_20200914_2034"), + ("users", "0027_auto_20200914_2052"), + ("users", "0028_auto_20200916_0008"), + ("users", "0029_ward"), + ("users", "0030_auto_20200921_1659"), + ("users", "0031_auto_20200927_1325"), + ("users", "0032_user_ward"), + ("users", "0033_auto_20201011_1908"), + ("users", "0034_auto_20201122_2013"), + ("users", "0035_auto_20210511_2105"), + ("users", "0036_auto_20210515_2048"), + ("users", "0037_auto_20210519_1826"), + ("users", "0038_user_alt_phone_number"), + ("users", "0039_auto_20210616_1634"), + ("users", "0040_auto_20210616_1821"), + ("users", "0041_user_asset"), + ("users", "0042_user_created_by"), + ("users", "0043_auto_20220624_1119"), + ("users", "0044_user_home_facility"), + ("users", "0045_auto_20230110_1120"), + ("users", "0046_auto_20230204_1733"), + ("users", "0047_user_external_id"), + ("users", "0048_auto_20230609_1411"), + ("users", "0049_auto_20230609_1413"), + ] + + dependencies = [ + ("facility", "0001_initial_squashed"), + ("users", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="asset", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="facility.Asset", + unique=True, + ), + ), + migrations.AddField( + model_name="user", + name="home_facility", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="facility.Facility", + ), + ), + ] diff --git a/care/users/migrations/0001_initial.py b/care/users/migrations_old/0001_initial.py similarity index 100% rename from care/users/migrations/0001_initial.py rename to care/users/migrations_old/0001_initial.py diff --git a/care/users/migrations/0002_auto_20200319_0634.py b/care/users/migrations_old/0002_auto_20200319_0634.py similarity index 100% rename from care/users/migrations/0002_auto_20200319_0634.py rename to care/users/migrations_old/0002_auto_20200319_0634.py diff --git a/care/users/migrations/0003_user_verified.py b/care/users/migrations_old/0003_user_verified.py similarity index 100% rename from care/users/migrations/0003_user_verified.py rename to care/users/migrations_old/0003_user_verified.py diff --git a/care/users/migrations/0004_auto_20200321_0556.py b/care/users/migrations_old/0004_auto_20200321_0556.py similarity index 100% rename from care/users/migrations/0004_auto_20200321_0556.py rename to care/users/migrations_old/0004_auto_20200321_0556.py diff --git a/care/users/migrations/0005_auto_20200321_0601.py b/care/users/migrations_old/0005_auto_20200321_0601.py similarity index 100% rename from care/users/migrations/0005_auto_20200321_0601.py rename to care/users/migrations_old/0005_auto_20200321_0601.py diff --git a/care/users/migrations/0006_user_deleted.py b/care/users/migrations_old/0006_user_deleted.py similarity index 100% rename from care/users/migrations/0006_user_deleted.py rename to care/users/migrations_old/0006_user_deleted.py diff --git a/care/users/migrations/0007_auto_20200321_2029.py b/care/users/migrations_old/0007_auto_20200321_2029.py similarity index 100% rename from care/users/migrations/0007_auto_20200321_2029.py rename to care/users/migrations_old/0007_auto_20200321_2029.py diff --git a/care/users/migrations/0008_auto_20200321_2035.py b/care/users/migrations_old/0008_auto_20200321_2035.py similarity index 100% rename from care/users/migrations/0008_auto_20200321_2035.py rename to care/users/migrations_old/0008_auto_20200321_2035.py diff --git a/care/users/migrations/0009_auto_20200325_1908.py b/care/users/migrations_old/0009_auto_20200325_1908.py similarity index 100% rename from care/users/migrations/0009_auto_20200325_1908.py rename to care/users/migrations_old/0009_auto_20200325_1908.py diff --git a/care/users/migrations/0010_populate_district.py b/care/users/migrations_old/0010_populate_district.py similarity index 100% rename from care/users/migrations/0010_populate_district.py rename to care/users/migrations_old/0010_populate_district.py diff --git a/care/users/migrations/0011_map_users_to_district.py b/care/users/migrations_old/0011_map_users_to_district.py similarity index 100% rename from care/users/migrations/0011_map_users_to_district.py rename to care/users/migrations_old/0011_map_users_to_district.py diff --git a/care/users/migrations/0012_auto_20200326_0342.py b/care/users/migrations_old/0012_auto_20200326_0342.py similarity index 100% rename from care/users/migrations/0012_auto_20200326_0342.py rename to care/users/migrations_old/0012_auto_20200326_0342.py diff --git a/care/users/migrations/0012_auto_20200326_1752.py b/care/users/migrations_old/0012_auto_20200326_1752.py similarity index 100% rename from care/users/migrations/0012_auto_20200326_1752.py rename to care/users/migrations_old/0012_auto_20200326_1752.py diff --git a/care/users/migrations/0013_auto_20200326_2021.py b/care/users/migrations_old/0013_auto_20200326_2021.py similarity index 100% rename from care/users/migrations/0013_auto_20200326_2021.py rename to care/users/migrations_old/0013_auto_20200326_2021.py diff --git a/care/users/migrations/0013_auto_20200327_0437.py b/care/users/migrations_old/0013_auto_20200327_0437.py similarity index 100% rename from care/users/migrations/0013_auto_20200327_0437.py rename to care/users/migrations_old/0013_auto_20200327_0437.py diff --git a/care/users/migrations/0014_restart_sequence_districts.py b/care/users/migrations_old/0014_restart_sequence_districts.py similarity index 100% rename from care/users/migrations/0014_restart_sequence_districts.py rename to care/users/migrations_old/0014_restart_sequence_districts.py diff --git a/care/users/migrations/0015_merge_20200327_1215.py b/care/users/migrations_old/0015_merge_20200327_1215.py similarity index 100% rename from care/users/migrations/0015_merge_20200327_1215.py rename to care/users/migrations_old/0015_merge_20200327_1215.py diff --git a/care/users/migrations/0016_auto_20200327_1954.py b/care/users/migrations_old/0016_auto_20200327_1954.py similarity index 100% rename from care/users/migrations/0016_auto_20200327_1954.py rename to care/users/migrations_old/0016_auto_20200327_1954.py diff --git a/care/users/migrations/0017_auto_20200328_2256.py b/care/users/migrations_old/0017_auto_20200328_2256.py similarity index 100% rename from care/users/migrations/0017_auto_20200328_2256.py rename to care/users/migrations_old/0017_auto_20200328_2256.py diff --git a/care/users/migrations/0018_auto_20200328_1853.py b/care/users/migrations_old/0018_auto_20200328_1853.py similarity index 100% rename from care/users/migrations/0018_auto_20200328_1853.py rename to care/users/migrations_old/0018_auto_20200328_1853.py diff --git a/care/users/migrations/0019_auto_20200328_2226.py b/care/users/migrations_old/0019_auto_20200328_2226.py similarity index 100% rename from care/users/migrations/0019_auto_20200328_2226.py rename to care/users/migrations_old/0019_auto_20200328_2226.py diff --git a/care/users/migrations/0020_auto_20200401_0930.py b/care/users/migrations_old/0020_auto_20200401_0930.py similarity index 100% rename from care/users/migrations/0020_auto_20200401_0930.py rename to care/users/migrations_old/0020_auto_20200401_0930.py diff --git a/care/users/migrations/0021_make_kerala_everyones_state.py b/care/users/migrations_old/0021_make_kerala_everyones_state.py similarity index 100% rename from care/users/migrations/0021_make_kerala_everyones_state.py rename to care/users/migrations_old/0021_make_kerala_everyones_state.py diff --git a/care/users/migrations/0022_auto_verify_users_with_facility.py b/care/users/migrations_old/0022_auto_verify_users_with_facility.py similarity index 100% rename from care/users/migrations/0022_auto_verify_users_with_facility.py rename to care/users/migrations_old/0022_auto_verify_users_with_facility.py diff --git a/care/users/migrations/0023_auto_20200413_1301.py b/care/users/migrations_old/0023_auto_20200413_1301.py similarity index 100% rename from care/users/migrations/0023_auto_20200413_1301.py rename to care/users/migrations_old/0023_auto_20200413_1301.py diff --git a/care/users/migrations/0024_auto_20200801_1844.py b/care/users/migrations_old/0024_auto_20200801_1844.py similarity index 100% rename from care/users/migrations/0024_auto_20200801_1844.py rename to care/users/migrations_old/0024_auto_20200801_1844.py diff --git a/care/users/migrations/0025_auto_20200914_2027.py b/care/users/migrations_old/0025_auto_20200914_2027.py similarity index 100% rename from care/users/migrations/0025_auto_20200914_2027.py rename to care/users/migrations_old/0025_auto_20200914_2027.py diff --git a/care/users/migrations/0026_auto_20200914_2034.py b/care/users/migrations_old/0026_auto_20200914_2034.py similarity index 100% rename from care/users/migrations/0026_auto_20200914_2034.py rename to care/users/migrations_old/0026_auto_20200914_2034.py diff --git a/care/users/migrations/0027_auto_20200914_2052.py b/care/users/migrations_old/0027_auto_20200914_2052.py similarity index 100% rename from care/users/migrations/0027_auto_20200914_2052.py rename to care/users/migrations_old/0027_auto_20200914_2052.py diff --git a/care/users/migrations/0028_auto_20200916_0008.py b/care/users/migrations_old/0028_auto_20200916_0008.py similarity index 100% rename from care/users/migrations/0028_auto_20200916_0008.py rename to care/users/migrations_old/0028_auto_20200916_0008.py diff --git a/care/users/migrations/0029_ward.py b/care/users/migrations_old/0029_ward.py similarity index 100% rename from care/users/migrations/0029_ward.py rename to care/users/migrations_old/0029_ward.py diff --git a/care/users/migrations/0030_auto_20200921_1659.py b/care/users/migrations_old/0030_auto_20200921_1659.py similarity index 100% rename from care/users/migrations/0030_auto_20200921_1659.py rename to care/users/migrations_old/0030_auto_20200921_1659.py diff --git a/care/users/migrations/0031_auto_20200927_1325.py b/care/users/migrations_old/0031_auto_20200927_1325.py similarity index 100% rename from care/users/migrations/0031_auto_20200927_1325.py rename to care/users/migrations_old/0031_auto_20200927_1325.py diff --git a/care/users/migrations/0032_user_ward.py b/care/users/migrations_old/0032_user_ward.py similarity index 100% rename from care/users/migrations/0032_user_ward.py rename to care/users/migrations_old/0032_user_ward.py diff --git a/care/users/migrations/0033_auto_20201011_1908.py b/care/users/migrations_old/0033_auto_20201011_1908.py similarity index 100% rename from care/users/migrations/0033_auto_20201011_1908.py rename to care/users/migrations_old/0033_auto_20201011_1908.py diff --git a/care/users/migrations/0034_auto_20201122_2013.py b/care/users/migrations_old/0034_auto_20201122_2013.py similarity index 100% rename from care/users/migrations/0034_auto_20201122_2013.py rename to care/users/migrations_old/0034_auto_20201122_2013.py diff --git a/care/users/migrations/0035_auto_20210511_2105.py b/care/users/migrations_old/0035_auto_20210511_2105.py similarity index 100% rename from care/users/migrations/0035_auto_20210511_2105.py rename to care/users/migrations_old/0035_auto_20210511_2105.py diff --git a/care/users/migrations/0036_auto_20210515_2048.py b/care/users/migrations_old/0036_auto_20210515_2048.py similarity index 100% rename from care/users/migrations/0036_auto_20210515_2048.py rename to care/users/migrations_old/0036_auto_20210515_2048.py diff --git a/care/users/migrations/0037_auto_20210519_1826.py b/care/users/migrations_old/0037_auto_20210519_1826.py similarity index 100% rename from care/users/migrations/0037_auto_20210519_1826.py rename to care/users/migrations_old/0037_auto_20210519_1826.py diff --git a/care/users/migrations/0038_user_alt_phone_number.py b/care/users/migrations_old/0038_user_alt_phone_number.py similarity index 100% rename from care/users/migrations/0038_user_alt_phone_number.py rename to care/users/migrations_old/0038_user_alt_phone_number.py diff --git a/care/users/migrations/0039_auto_20210616_1634.py b/care/users/migrations_old/0039_auto_20210616_1634.py similarity index 100% rename from care/users/migrations/0039_auto_20210616_1634.py rename to care/users/migrations_old/0039_auto_20210616_1634.py diff --git a/care/users/migrations/0040_auto_20210616_1821.py b/care/users/migrations_old/0040_auto_20210616_1821.py similarity index 100% rename from care/users/migrations/0040_auto_20210616_1821.py rename to care/users/migrations_old/0040_auto_20210616_1821.py diff --git a/care/users/migrations/0041_user_asset.py b/care/users/migrations_old/0041_user_asset.py similarity index 100% rename from care/users/migrations/0041_user_asset.py rename to care/users/migrations_old/0041_user_asset.py diff --git a/care/users/migrations/0042_user_created_by.py b/care/users/migrations_old/0042_user_created_by.py similarity index 100% rename from care/users/migrations/0042_user_created_by.py rename to care/users/migrations_old/0042_user_created_by.py diff --git a/care/users/migrations/0043_auto_20220624_1119.py b/care/users/migrations_old/0043_auto_20220624_1119.py similarity index 100% rename from care/users/migrations/0043_auto_20220624_1119.py rename to care/users/migrations_old/0043_auto_20220624_1119.py diff --git a/care/users/migrations/0044_user_home_facility.py b/care/users/migrations_old/0044_user_home_facility.py similarity index 100% rename from care/users/migrations/0044_user_home_facility.py rename to care/users/migrations_old/0044_user_home_facility.py diff --git a/care/users/migrations/0045_auto_20230110_1120.py b/care/users/migrations_old/0045_auto_20230110_1120.py similarity index 100% rename from care/users/migrations/0045_auto_20230110_1120.py rename to care/users/migrations_old/0045_auto_20230110_1120.py diff --git a/care/users/migrations/0046_auto_20230204_1733.py b/care/users/migrations_old/0046_auto_20230204_1733.py similarity index 100% rename from care/users/migrations/0046_auto_20230204_1733.py rename to care/users/migrations_old/0046_auto_20230204_1733.py diff --git a/care/users/migrations/0047_user_external_id.py b/care/users/migrations_old/0047_user_external_id.py similarity index 100% rename from care/users/migrations/0047_user_external_id.py rename to care/users/migrations_old/0047_user_external_id.py diff --git a/care/users/migrations/0048_auto_20230609_1411.py b/care/users/migrations_old/0048_auto_20230609_1411.py similarity index 100% rename from care/users/migrations/0048_auto_20230609_1411.py rename to care/users/migrations_old/0048_auto_20230609_1411.py diff --git a/care/users/migrations/0049_auto_20230609_1413.py b/care/users/migrations_old/0049_auto_20230609_1413.py similarity index 100% rename from care/users/migrations/0049_auto_20230609_1413.py rename to care/users/migrations_old/0049_auto_20230609_1413.py diff --git a/care/users/migrations_old/__init__.py b/care/users/migrations_old/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From d9536374d075f252f56ff0303feda617258e71e8 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 17:05:05 +0530 Subject: [PATCH 06/24] Convert partial indexes to unique constraints and remove dependency Fixes #1355 --- .../migrations/0001_initial_squashed.py | 46 ------------ .../migrations/0002_auto_20230613_1657.py | 72 +++++++++++++++++++ care/facility/models/facility.py | 17 +++-- care/facility/models/inventory.py | 17 +++-- care/facility/models/patient.py | 9 ++- .../users/migrations/0001_initial_squashed.py | 10 --- .../migrations/0003_auto_20230613_1657.py | 24 +++++++ care/users/models.py | 9 ++- pyproject.toml | 1 - requirements/base.txt | 1 - 10 files changed, 126 insertions(+), 80 deletions(-) create mode 100644 care/facility/migrations/0002_auto_20230613_1657.py create mode 100644 care/users/migrations/0003_auto_20230613_1657.py diff --git a/care/facility/migrations/0001_initial_squashed.py b/care/facility/migrations/0001_initial_squashed.py index ff4d9b890e..b5ae3f80de 100644 --- a/care/facility/migrations/0001_initial_squashed.py +++ b/care/facility/migrations/0001_initial_squashed.py @@ -9,7 +9,6 @@ import django.utils.timezone import fernet_fields.fields import multiselectfield.db.fields -import partial_index import simple_history.models from django.conf import settings from django.db import migrations, models @@ -6968,15 +6967,6 @@ class Migration(migrations.Migration): fields=["-created_date"], name="facility_in_created_ea2255_idx" ), ), - migrations.AddIndex( - model_name="hospitaldoctors", - index=partial_index.PartialIndex( - fields=["facility", "area"], - name="facility_ho_facilit_ec08f4_partial", - unique=True, - where=partial_index.PQ(deleted=False), - ), - ), migrations.AlterUniqueTogether( name="facilityuser", unique_together={("facility", "user")}, @@ -7019,24 +7009,6 @@ class Migration(migrations.Migration): name="cons_facilitylocalgovtbody_only_one_null", ), ), - migrations.AddIndex( - model_name="facilityinventorysummary", - index=partial_index.PartialIndex( - fields=["facility", "item"], - name="facility_fa_facilit_ff33b8_partial", - unique=True, - where=partial_index.PQ(deleted=False), - ), - ), - migrations.AddIndex( - model_name="facilityinventoryminquantity", - index=partial_index.PartialIndex( - fields=["facility", "item"], - name="facility_fa_facilit_a9eb9a_partial", - unique=True, - where=partial_index.PQ(deleted=False), - ), - ), migrations.AddIndex( model_name="facilityinventoryburnrate", index=models.Index( @@ -7047,15 +7019,6 @@ class Migration(migrations.Migration): name="facilityinventoryburnrate", unique_together={("facility", "item")}, ), - migrations.AddIndex( - model_name="facilitycapacity", - index=partial_index.PartialIndex( - fields=["facility", "room_type"], - name="facility_fa_facilit_ec2b0e_partial", - unique=True, - where=partial_index.PQ(deleted=False), - ), - ), migrations.AddIndex( model_name="districtscopedsummary", index=models.Index( @@ -7079,15 +7042,6 @@ class Migration(migrations.Migration): name="facility_di_created_45003b_idx", ), ), - migrations.AddIndex( - model_name="disease", - index=partial_index.PartialIndex( - fields=["patient", "disease"], - name="facility_di_patient_640ef7_partial", - unique=True, - where=partial_index.PQ(deleted=False), - ), - ), migrations.AddConstraint( model_name="asset", constraint=models.UniqueConstraint( diff --git a/care/facility/migrations/0002_auto_20230613_1657.py b/care/facility/migrations/0002_auto_20230613_1657.py new file mode 100644 index 0000000000..33794c0aa2 --- /dev/null +++ b/care/facility/migrations/0002_auto_20230613_1657.py @@ -0,0 +1,72 @@ +# Generated by Django 2.2.11 on 2023-06-13 11:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0001_initial_squashed"), + ] + + operations = [ + migrations.RunSQL( + sql="DROP INDEX IF EXISTS facility_di_patient_640ef7_partial", + reverse_sql=migrations.RunSQL.noop, + ), + migrations.RunSQL( + sql="DROP INDEX IF EXISTS facility_fa_facilit_ec2b0e_partial", + reverse_sql=migrations.RunSQL.noop, + ), + migrations.RunSQL( + sql="DROP INDEX IF EXISTS facility_fa_facilit_a9eb9a_partial", + reverse_sql=migrations.RunSQL.noop, + ), + migrations.RunSQL( + sql="DROP INDEX IF EXISTS facility_fa_facilit_ff33b8_partial", + reverse_sql=migrations.RunSQL.noop, + ), + migrations.RunSQL( + sql="DROP INDEX IF EXISTS facility_ho_facilit_ec08f4_partial", + reverse_sql=migrations.RunSQL.noop, + ), + migrations.AddConstraint( + model_name="disease", + constraint=models.UniqueConstraint( + condition=models.Q(deleted=False), + fields=("patient", "disease"), + name="unique_patient_disease", + ), + ), + migrations.AddConstraint( + model_name="facilitycapacity", + constraint=models.UniqueConstraint( + condition=models.Q(deleted=False), + fields=("facility", "room_type"), + name="unique_facility_room_type", + ), + ), + migrations.AddConstraint( + model_name="facilityinventoryminquantity", + constraint=models.UniqueConstraint( + condition=models.Q(deleted=False), + fields=("facility", "item"), + name="unique_facility_item_min_quantity", + ), + ), + migrations.AddConstraint( + model_name="facilityinventorysummary", + constraint=models.UniqueConstraint( + condition=models.Q(deleted=False), + fields=("facility", "item"), + name="unique_facility_item_summary", + ), + ), + migrations.AddConstraint( + model_name="hospitaldoctors", + constraint=models.UniqueConstraint( + condition=models.Q(deleted=False), + fields=("facility", "area"), + name="unique_facility_doctor", + ), + ), + ] diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index 476612f9d1..a407be8a63 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -3,7 +3,6 @@ from django.core.validators import MinValueValidator from django.db import models from multiselectfield import MultiSelectField -from partial_index import PQ, PartialIndex from simple_history.models import HistoricalRecords from care.facility.models import FacilityBaseModel, phone_number_regex, reverse_choices @@ -269,9 +268,11 @@ def __str__(self): return str(self.facility) + str(self.count) class Meta: - indexes = [ - PartialIndex( - fields=["facility", "area"], unique=True, where=PQ(deleted=False) + constraints = [ + models.UniqueConstraint( + fields=["facility", "area"], + condition=models.Q(deleted=False), + name="unique_facility_doctor", ) ] @@ -294,9 +295,11 @@ class FacilityCapacity(FacilityBaseModel, FacilityRelatedPermissionMixin): history = HistoricalRecords() class Meta: - indexes = [ - PartialIndex( - fields=["facility", "room_type"], unique=True, where=PQ(deleted=False) + constraints = [ + models.UniqueConstraint( + fields=["facility", "room_type"], + condition=models.Q(deleted=False), + name="unique_facility_room_type", ) ] verbose_name_plural = "Facility Capacities" diff --git a/care/facility/models/inventory.py b/care/facility/models/inventory.py index 5719019d13..934b0128f4 100644 --- a/care/facility/models/inventory.py +++ b/care/facility/models/inventory.py @@ -1,7 +1,6 @@ from django.contrib.auth import get_user_model from django.db import models from django.db.models import Index -from partial_index import PQ, PartialIndex from care.facility.models import FacilityBaseModel from care.facility.models.mixins.permissions.facility import ( @@ -138,9 +137,11 @@ class FacilityInventorySummary(FacilityBaseModel, FacilityRelatedPermissionMixin is_low = models.BooleanField(default=False) class Meta: - indexes = [ - PartialIndex( - fields=["facility", "item"], unique=True, where=PQ(deleted=False) + constraints = [ + models.UniqueConstraint( + fields=["facility", "item"], + condition=models.Q(deleted=False), + name="unique_facility_item_summary", ) ] @@ -159,9 +160,11 @@ class FacilityInventoryMinQuantity(FacilityBaseModel, FacilityRelatedPermissionM min_quantity = models.FloatField(default=0) class Meta: - indexes = [ - PartialIndex( - fields=["facility", "item"], unique=True, where=PQ(deleted=False) + constraints = [ + models.UniqueConstraint( + fields=["facility", "item"], + condition=models.Q(deleted=False), + name="unique_facility_item_min_quantity", ) ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 729bd4f8f5..045760a507 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -4,7 +4,6 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from fernet_fields import EncryptedCharField, EncryptedIntegerField -from partial_index import PQ, PartialIndex from simple_history.models import HistoricalRecords from care.facility.models import ( @@ -697,11 +696,11 @@ class Disease(models.Model): objects = BaseManager() class Meta: - indexes = [ - PartialIndex( + constraints = [ + models.UniqueConstraint( fields=["patient", "disease"], - unique=True, - where=PQ(deleted=False), + condition=models.Q(deleted=False), + name="unique_patient_disease", ) ] diff --git a/care/users/migrations/0001_initial_squashed.py b/care/users/migrations/0001_initial_squashed.py index 163fede411..ec915df6ba 100644 --- a/care/users/migrations/0001_initial_squashed.py +++ b/care/users/migrations/0001_initial_squashed.py @@ -5,7 +5,6 @@ import django.core.validators import django.db.models.deletion import django.utils.timezone -import partial_index from django.conf import settings from django.db import migrations, models @@ -509,15 +508,6 @@ class Migration(migrations.Migration): to="users.Ward", ), ), - migrations.AddIndex( - model_name="userskill", - index=partial_index.PartialIndex( - fields=["skill", "user"], - name="users_users_skill_i_6ebc32_partial", - unique=True, - where=partial_index.PQ(deleted=False), - ), - ), migrations.AlterUniqueTogether( name="localbody", unique_together={("district", "body_type", "name")}, diff --git a/care/users/migrations/0003_auto_20230613_1657.py b/care/users/migrations/0003_auto_20230613_1657.py new file mode 100644 index 0000000000..59932ae3bb --- /dev/null +++ b/care/users/migrations/0003_auto_20230613_1657.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.11 on 2023-06-13 11:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("users", "0002_auto_20230613_1622"), + ] + + operations = [ + migrations.RunSQL( + sql="DROP INDEX IF EXISTS users_users_skill_i_6ebc32_partial", + reverse_sql=migrations.RunSQL.noop, + ), + migrations.AddConstraint( + model_name="userskill", + constraint=models.UniqueConstraint( + condition=models.Q(deleted=False), + fields=("skill", "user"), + name="unique_user_skill", + ), + ), + ] diff --git a/care/users/models.py b/care/users/models.py index 166460aa0f..741609f016 100644 --- a/care/users/models.py +++ b/care/users/models.py @@ -6,7 +6,6 @@ from django.db import models from django.urls import reverse from django.utils.translation import ugettext_lazy as _ -from partial_index import PQ, PartialIndex from care.utils.models.base import BaseModel @@ -168,8 +167,12 @@ class UserSkill(BaseModel): skill = models.ForeignKey("Skill", on_delete=models.CASCADE, null=True, blank=True) class Meta: - indexes = [ - PartialIndex(fields=["skill", "user"], unique=True, where=PQ(deleted=False)) + constraints = [ + models.UniqueConstraint( + fields=["skill", "user"], + condition=models.Q(deleted=False), + name="unique_user_skill", + ) ] diff --git a/pyproject.toml b/pyproject.toml index 839b857557..a6ae114982 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,6 @@ known_third_party = [ "jsonschema", "jwt", "multiselectfield", - "partial_index", "phonenumber_field", "phonenumbers", "pytz", diff --git a/requirements/base.txt b/requirements/base.txt index dabc29006d..cfc2428401 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -20,7 +20,6 @@ drf-yasg==1.17.1 # For Api Docs django-filter==2.4.0 drf-nested-routers==0.91 django-multiselectfield==0.1.12 # https://github.com/goinnn/django-multiselectfield -django-partial-index==0.6.0 # https://github.com/mattiaslinnap/django-partial-index/blob/master/README.md django-simple-history==2.8.0 # https://django-simple-history.readthedocs.io/en/latest/quick_start.html django-ratelimit==2.0.0 # Limiting Requests django-fernet-fields==0.6 # https://django-fernet-fields.readthedocs.io/en/latest/ From e7fb7cb4e90a6cd4b966718fc256d138c2faae36 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 17:06:09 +0530 Subject: [PATCH 07/24] remove phone number field and use consistent phone number validation Fixes #1243 --- care/facility/api/serializers/patient.py | 6 ---- care/facility/api/serializers/shifting.py | 7 +---- care/users/api/serializers/user.py | 6 ---- .../phonenumber_ispossible_field.py | 20 ------------- .../test_phonenumber_ispossible_field.py | 29 ------------------- requirements/base.txt | 2 -- 6 files changed, 1 insertion(+), 69 deletions(-) delete mode 100644 care/utils/serializer/phonenumber_ispossible_field.py delete mode 100644 care/utils/serializer/tests/test_phonenumber_ispossible_field.py diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 9326fc03a3..d3587e3b33 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -48,9 +48,6 @@ from care.utils.notification_handler import NotificationGenerator from care.utils.queryset.facility import get_home_facility_queryset from care.utils.serializer.external_id_field import ExternalIdSerializerField -from care.utils.serializer.phonenumber_ispossible_field import ( - PhoneNumberIsPossibleField, -) from config.serializers import ChoiceField @@ -165,8 +162,6 @@ class Meta: model = PatientTeleConsultation fields = "__all__" - phone_number = PhoneNumberIsPossibleField() - facility = ExternalIdSerializerField( queryset=Facility.objects.all(), required=False ) @@ -417,7 +412,6 @@ def create(self, validated_data): class PatientSearchSerializer(serializers.ModelSerializer): gender = ChoiceField(choices=GENDER_CHOICES) - phone_number = PhoneNumberIsPossibleField() patient_id = serializers.UUIDField(source="external_id", read_only=True) # facility_id = serializers.UUIDField(read_only=True, allow_null=True) diff --git a/care/facility/api/serializers/shifting.py b/care/facility/api/serializers/shifting.py index b8e7e18bf9..782ace2e91 100644 --- a/care/facility/api/serializers/shifting.py +++ b/care/facility/api/serializers/shifting.py @@ -27,9 +27,6 @@ from care.users.api.serializers.user import UserBaseMinimumSerializer from care.utils.notification_handler import NotificationGenerator from care.utils.serializer.external_id_field import ExternalIdSerializerField -from care.utils.serializer.phonenumber_ispossible_field import ( - PhoneNumberIsPossibleField, -) from config.serializers import ChoiceField @@ -223,9 +220,7 @@ class ShiftingSerializer(serializers.ModelSerializer): ambulance_driver_name = serializers.CharField( required=False, allow_null=True, allow_blank=True ) - ambulance_phone_number = PhoneNumberIsPossibleField( - required=False, allow_null=True, allow_blank=True - ) + ambulance_number = serializers.CharField( required=False, allow_null=True, allow_blank=True ) diff --git a/care/users/api/serializers/user.py b/care/users/api/serializers/user.py index e3b0edc0db..4e637c003b 100644 --- a/care/users/api/serializers/user.py +++ b/care/users/api/serializers/user.py @@ -16,9 +16,6 @@ from care.users.models import GENDER_CHOICES from care.utils.queryset.facility import get_home_facility_queryset from care.utils.serializer.external_id_field import ExternalIdSerializerField -from care.utils.serializer.phonenumber_ispossible_field import ( - PhoneNumberIsPossibleField, -) from config.serializers import ChoiceField User = get_user_model() @@ -28,8 +25,6 @@ class SignUpSerializer(serializers.ModelSerializer): user_type = ChoiceField(choices=User.TYPE_CHOICES) gender = ChoiceField(choices=GENDER_CHOICES) password = serializers.CharField(write_only=True) - phone_number = PhoneNumberIsPossibleField() - alt_phone_number = PhoneNumberIsPossibleField(required=False, allow_blank=True) class Meta: model = User @@ -269,7 +264,6 @@ class UserSerializer(SignUpSerializer): local_body_object = LocalBodySerializer(source="local_body", read_only=True) district_object = DistrictSerializer(source="district", read_only=True) state_object = StateSerializer(source="state", read_only=True) - alt_phone_number = PhoneNumberIsPossibleField(required=False, allow_blank=True) home_facility_object = FacilityBareMinimumSerializer( source="home_facility", read_only=True ) diff --git a/care/utils/serializer/phonenumber_ispossible_field.py b/care/utils/serializer/phonenumber_ispossible_field.py deleted file mode 100644 index 8f147e4479..0000000000 --- a/care/utils/serializer/phonenumber_ispossible_field.py +++ /dev/null @@ -1,20 +0,0 @@ -import phonenumbers -from django.utils.translation import gettext_lazy as _ -from phonenumber_field.phonenumber import to_python -from rest_framework import serializers -from rest_framework.exceptions import ValidationError - - -class PhoneNumberIsPossibleField(serializers.CharField): - default_error_messages = {"invalid": _("Enter a valid phone number.")} - - def to_internal_value(self, data): - if self.allow_blank and (not data): - return None - phone_number = to_python(data) - if phone_number and not phonenumbers.is_possible_number(phone_number): - # attempting to check if this is a possible Indian number - phone_number = to_python(data, region="IN") - if phone_number and not phonenumbers.is_possible_number(phone_number): - raise ValidationError(self.error_messages["invalid"]) - return phone_number diff --git a/care/utils/serializer/tests/test_phonenumber_ispossible_field.py b/care/utils/serializer/tests/test_phonenumber_ispossible_field.py deleted file mode 100644 index 90afbec313..0000000000 --- a/care/utils/serializer/tests/test_phonenumber_ispossible_field.py +++ /dev/null @@ -1,29 +0,0 @@ -from unittest import TestCase - -from rest_framework.exceptions import ValidationError - -from care.utils.serializer.phonenumber_ispossible_field import ( - PhoneNumberIsPossibleField, -) - - -class TestPhoneNumberIsPossibleField(TestCase): - def test_phone_number(self): - # map -> input value -> output value - # if output value is None, the it is invalid - - test_cases = { - "7795937091": "+917795937091", - "07795937091": "+917795937091", - "+917795937091": "+917795937091", - "+1 470-485-8757": "+14704858757", - "+18944775567": "+18944775567", - "+911234": None, - } - - for ip, op in test_cases.items(): - if op is None: - with self.assertRaises(ValidationError): - PhoneNumberIsPossibleField().to_internal_value(ip) - else: - self.assertEqual(PhoneNumberIsPossibleField().to_internal_value(ip), op) diff --git a/requirements/base.txt b/requirements/base.txt index cfc2428401..8be91c1008 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -27,8 +27,6 @@ dry-rest-permissions==0.1.10 # For permissions handling django-cors-headers==3.2.1 django-watchman==1.1.0 # For Status Endpoints django-maintenance-mode==0.14.0 # Maintenance mode -django-phonenumber-field==4.0.0 -phonenumberslite==8.12.1 django-queryset-csv==1.1.0 django-rest-passwordreset==1.1.0 healthy-django>=0.1.0 From f585952238863b5bc7209f81dcd59fea47c35075 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 13 Jun 2023 17:09:10 +0530 Subject: [PATCH 08/24] Remove PatientSearch model Fixes #1351 --- care/facility/api/serializers/patient.py | 5 +- .../api/serializers/patient_search.py | 19 ----- care/facility/api/viewsets/patient.py | 14 +--- care/facility/api/viewsets/patient_search.py | 47 ------------- .../migrations/0001_initial_squashed.py | 9 +-- .../migrations/0003_auto_20230614_1048.py | 19 +++++ care/facility/models/patient.py | 70 ------------------- config/api_router.py | 6 +- config/settings/deployment.py | 8 --- config/settings/local.py | 10 +-- config/settings/test.py | 10 +-- pyproject.toml | 1 - requirements/base.txt | 1 - 13 files changed, 29 insertions(+), 190 deletions(-) delete mode 100644 care/facility/api/serializers/patient_search.py delete mode 100644 care/facility/api/viewsets/patient_search.py create mode 100644 care/facility/migrations/0003_auto_20230614_1048.py diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index d3587e3b33..788bb2b8f4 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -24,7 +24,6 @@ PatientMetaInfo, PatientNotes, PatientRegistration, - PatientSearch, ) from care.facility.models.notification import Notification from care.facility.models.patient_base import ( @@ -117,7 +116,6 @@ class Meta: "created_by", "deleted", "ongoing_medication", - "patient_search_id", "year_of_birth", "meta_info", "countries_travelled_old", @@ -215,7 +213,6 @@ class Meta: model = PatientRegistration exclude = ( "deleted", - "patient_search_id", "year_of_birth", "countries_travelled_old", "external_id", @@ -417,7 +414,7 @@ class PatientSearchSerializer(serializers.ModelSerializer): # facility_id = serializers.UUIDField(read_only=True, allow_null=True) class Meta: - model = PatientSearch + model = PatientRegistration exclude = ( "date_of_birth", "year_of_birth", diff --git a/care/facility/api/serializers/patient_search.py b/care/facility/api/serializers/patient_search.py deleted file mode 100644 index 92a0d678bd..0000000000 --- a/care/facility/api/serializers/patient_search.py +++ /dev/null @@ -1,19 +0,0 @@ -from rest_framework import serializers - -from care.facility.api.serializers.facility import FacilityBasicInfoSerializer -from care.facility.models import GENDER_CHOICES, PatientSearch -from config.serializers import ChoiceField - - -class PatientScopedSearchSerializer(serializers.ModelSerializer): - gender = ChoiceField(choices=GENDER_CHOICES) - facility = FacilityBasicInfoSerializer() - id = serializers.CharField(source="patient_external_id") - facility = serializers.UUIDField( - source="facility.external_id", allow_null=True, read_only=True - ) - facility_object = FacilityBasicInfoSerializer(source="facility", read_only=True) - - class Meta: - model = PatientSearch - exclude = ("patient_id", "external_id") diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index 2981012b38..f9ccf342e0 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -44,7 +44,6 @@ FacilityPatientStatsHistory, PatientNotes, PatientRegistration, - PatientSearch, ShiftingRequest, ) from care.facility.models.base import covert_choice_dict @@ -396,9 +395,7 @@ def list(self, request, *args, **kwargs): @action(detail=True, methods=["POST"]) def transfer(self, request, *args, **kwargs): - patient = PatientRegistration.objects.get( - id=PatientSearch.objects.get(external_id=kwargs["external_id"]).patient_id - ) + patient = PatientRegistration.objects.get(external_id=kwargs["external_id"]) if patient.allow_transfer is False: return Response( @@ -411,9 +408,7 @@ def transfer(self, request, *args, **kwargs): serializer.is_valid(raise_exception=True) serializer.save() - patient = PatientRegistration.objects.get( - id=PatientSearch.objects.get(external_id=kwargs["external_id"]).patient_id - ) + patient = PatientRegistration.objects.get(external_id=kwargs["external_id"]) response_serializer = self.get_serializer(patient) # Update all Active Shifting Request to Rejected @@ -493,7 +488,7 @@ class PatientSearchSetPagination(PageNumberPagination): class PatientSearchViewSet(UserAccessMixin, ListModelMixin, GenericViewSet): http_method_names = ["get"] - queryset = PatientSearch.objects.all() + queryset = PatientRegistration.objects.all() serializer_class = PatientSearchSerializer permission_classes = (IsAuthenticated, DRYPermissions) pagination_class = PatientSearchSetPagination @@ -557,9 +552,6 @@ def get_queryset(self): return queryset - def retrieve(self, request, *args, **kwargs): - raise NotImplementedError() - def list(self, request, *args, **kwargs): """ Patient Search diff --git a/care/facility/api/viewsets/patient_search.py b/care/facility/api/viewsets/patient_search.py deleted file mode 100644 index 6395864ab2..0000000000 --- a/care/facility/api/viewsets/patient_search.py +++ /dev/null @@ -1,47 +0,0 @@ -from django_filters import rest_framework as filters -from dry_rest_permissions.generics import DRYPermissions -from rest_framework.mixins import ListModelMixin -from rest_framework.permissions import IsAuthenticated -from rest_framework.viewsets import GenericViewSet - -from care.facility.api.serializers.patient_search import PatientScopedSearchSerializer -from care.facility.models import PatientSearch -from care.users.models import User - - -class PatientSearchFilter(filters.FilterSet): - name = filters.CharFilter(field_name="name", lookup_expr="icontains") - phone_number = filters.CharFilter( - field_name="phone_number", lookup_expr="icontains" - ) - is_active = filters.BooleanFilter(field_name="is_active") - facility = filters.UUIDFilter(field_name="facility__external_id") - - -class PatientScopedSearchViewSet(ListModelMixin, GenericViewSet): - serializer_class = PatientScopedSearchSerializer - queryset = PatientSearch.objects.all() - - permission_classes = ( - IsAuthenticated, - DRYPermissions, - ) - - filter_backends = (filters.DjangoFilterBackend,) - - filterset_class = PatientSearchFilter - - def get_queryset(self): - user = self.request.user - # queryset = self.queryset.filter(facility__external_id=self.kwargs.get("facility_external_id")) - queryset = self.queryset.filter(facility__isnull=False) - if user.is_superuser: - return self.queryset # Gets patient without a facility as well - elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]: - return queryset.filter(facility__state=user.state) - elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictAdmin"]: - return queryset.filter(facility__district=user.district) - return queryset.filter(facility__users__id__exact=user.id) - - def list(self, request, *args, **kwargs): - return super(PatientScopedSearchViewSet, self).list(request, *args, **kwargs) diff --git a/care/facility/migrations/0001_initial_squashed.py b/care/facility/migrations/0001_initial_squashed.py index b5ae3f80de..35ac30edb2 100644 --- a/care/facility/migrations/0001_initial_squashed.py +++ b/care/facility/migrations/0001_initial_squashed.py @@ -7,7 +7,6 @@ import django.core.validators import django.db.models.deletion import django.utils.timezone -import fernet_fields.fields import multiselectfield.db.fields import simple_history.models from django.conf import settings @@ -3047,9 +3046,7 @@ class Migration(migrations.Migration): ), ( "patient_search_id", - fernet_fields.fields.EncryptedIntegerField( - help_text="FKey to PatientSearch", null=True - ), + models.IntegerField(help_text="FKey to PatientSearch", null=True), ), ( "date_of_receipt_of_information", @@ -4413,7 +4410,7 @@ class Migration(migrations.Migration): models.DateTimeField(auto_now=True, db_index=True, null=True), ), ("deleted", models.BooleanField(db_index=True, default=False)), - ("patient_id", fernet_fields.fields.EncryptedIntegerField()), + ("patient_id", models.IntegerField()), ("name", models.CharField(max_length=120)), ( "gender", @@ -4427,7 +4424,7 @@ class Migration(migrations.Migration): ("state_id", models.IntegerField()), ( "patient_external_id", - fernet_fields.fields.EncryptedCharField(default="", max_length=100), + models.CharField(default="", max_length=100), ), ("allow_transfer", models.BooleanField(default=True)), ("is_active", models.BooleanField(default=True)), diff --git a/care/facility/migrations/0003_auto_20230614_1048.py b/care/facility/migrations/0003_auto_20230614_1048.py new file mode 100644 index 0000000000..ec6a7f9d74 --- /dev/null +++ b/care/facility/migrations/0003_auto_20230614_1048.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.11 on 2023-06-14 05:18 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0002_auto_20230613_1657"), + ] + + operations = [ + migrations.RemoveField( + model_name="patientregistration", + name="patient_search_id", + ), + migrations.DeleteModel( + name="PatientSearch", + ), + ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 045760a507..b9ffff2cd6 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -3,7 +3,6 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models -from fernet_fields import EncryptedCharField, EncryptedIntegerField from simple_history.models import HistoricalRecords from care.facility.models import ( @@ -263,9 +262,6 @@ class TestTypeEnum(enum.Enum): help_text="Not active when discharged, or removed from the watchlist", ) - patient_search_id = EncryptedIntegerField( - help_text="FKey to PatientSearch", null=True - ) date_of_receipt_of_information = models.DateTimeField( null=True, blank=True, @@ -477,37 +473,8 @@ def save(self, *args, **kwargs) -> None: else datetime.datetime.now() ) - is_create = self.pk is None self._alias_recovery_to_recovered() super().save(*args, **kwargs) - if is_create or self.patient_search_id is None: - ps = PatientSearch.objects.create( - patient_external_id=self.external_id, - name=self.name, - gender=self.gender, - phone_number=self.phone_number, - date_of_birth=self.date_of_birth, - year_of_birth=self.year_of_birth, - state_id=self.state_id, - patient_id=self.pk, - facility=self.facility, - allow_transfer=self.allow_transfer, - ) - self.patient_search_id = ps.pk - self.save() - else: - PatientSearch.objects.filter(pk=self.patient_search_id).update( - patient_external_id=self.external_id, - name=self.name, - gender=self.gender, - phone_number=self.phone_number, - date_of_birth=self.date_of_birth, - year_of_birth=self.year_of_birth, - state_id=self.state_id, - facility=self.facility, - allow_transfer=self.allow_transfer, - is_active=self.is_active, - ) CSV_MAPPING = { # Patient Details @@ -566,43 +533,6 @@ def format_as_time(time): } -class PatientSearch(PatientBaseModel): - patient_id = EncryptedIntegerField() - - name = models.CharField(max_length=120) - gender = models.IntegerField(choices=GENDER_CHOICES) - phone_number = models.CharField(max_length=14) - date_of_birth = models.DateField(null=True) - year_of_birth = models.IntegerField() - state_id = models.IntegerField() - - facility = models.ForeignKey("Facility", on_delete=models.SET_NULL, null=True) - patient_external_id = EncryptedCharField(max_length=100, default="") - - allow_transfer = models.BooleanField(default=True) - is_active = models.BooleanField(default=True) - - class Meta: - indexes = [ - models.Index(fields=["year_of_birth", "date_of_birth", "phone_number"]), - models.Index(fields=["year_of_birth", "phone_number"]), - ] - - @staticmethod - def has_read_permission(request): - if ( - request.user.is_superuser - or request.user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"] - ): - return True - elif ( - request.user.user_type >= User.TYPE_VALUE_MAP["Staff"] - and request.user.verified - ): - return True - return False - - class PatientMetaInfo(models.Model): class OccupationEnum(enum.Enum): STUDENT = 1 diff --git a/config/api_router.py b/config/api_router.py index 4882b4d329..b01a03b668 100644 --- a/config/api_router.py +++ b/config/api_router.py @@ -15,9 +15,9 @@ ) from care.facility.api.viewsets.bed import ( AssetBedViewSet, - PatientAssetBedViewSet, BedViewSet, ConsultationBedViewSet, + PatientAssetBedViewSet, ) from care.facility.api.viewsets.daily_round import DailyRoundsViewSet from care.facility.api.viewsets.facility import AllFacilityViewSet, FacilityViewSet @@ -50,7 +50,6 @@ from care.facility.api.viewsets.patient_otp import PatientMobileOTPViewSet from care.facility.api.viewsets.patient_otp_data import OTPPatientDataViewSet from care.facility.api.viewsets.patient_sample import PatientSampleViewSet -from care.facility.api.viewsets.patient_search import PatientScopedSearchViewSet from care.facility.api.viewsets.prescription import ( ConsultationPrescriptionViewSet, MedicineAdministrationViewSet, @@ -137,9 +136,6 @@ # Patient Sample router.register("test_sample", PatientSampleViewSet) -# Patient Search -router.register("patient_search", PatientScopedSearchViewSet) - # Summarisation router.register( "facility_summary", FacilityCapacitySummaryViewSet, basename="summary-facility" diff --git a/config/settings/deployment.py b/config/settings/deployment.py index 76c5b0c2b8..91d6a1266c 100644 --- a/config/settings/deployment.py +++ b/config/settings/deployment.py @@ -13,15 +13,7 @@ # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#secret-key SECRET_KEY = env("DJANGO_SECRET_KEY") -# The first key will be used to encrypt all new data, and decryption of existing values will be attempted -# with all given keys in order. This is useful for key rotation: place a new key at the head of the list -# for use with all new or changed data, but existing values encrypted with old keys will still be accessible - -FERNET_KEYS = env.list( - "FERNET_SECRET_KEY", - default=["76d7e8e551f23cc5b648ec88d01b6d2b26d72b148e2b2a3b02bf77037f236a8b"], -) # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts ALLOWED_HOSTS = json.loads(env("DJANGO_ALLOWED_HOSTS", default='["*"]')) # noqa F405 diff --git a/config/settings/local.py b/config/settings/local.py index 3e917901d8..bfcaf28793 100644 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -11,15 +11,7 @@ "DJANGO_SECRET_KEY", default="eXZQzOzx8gV38rDG0Z0fFZWweUGl3LwMZ9aTKqJiXQTI0nKMh0Z7sbHfqT8KFEnd", ) -# The first key will be used to encrypt all new data, and decryption of existing values will be attempted -# with all given keys in order. This is useful for key rotation: place a new key at the head of the list -# for use with all new or changed data, but existing values encrypted with old keys will still be accessible -FERNET_KEYS = [ - env( - "FERNET_SECRET_KEY_1", - default="f685a83652d782188382a3f2696e623a764c8012b1488d2fc5bc6460cddc7878", - ) -] + # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hostsRUNSERVER_PLUS_PRINT_SQL_TRUNCATE # CACHES diff --git a/config/settings/test.py b/config/settings/test.py index bd05bb751e..be4a22d593 100644 --- a/config/settings/test.py +++ b/config/settings/test.py @@ -12,15 +12,7 @@ "DJANGO_SECRET_KEY", default="GlSRVXhTNJXx3Fnu5HUYlgeoMIXy3rl76CIhfOAEHtXE4jrGAEDbAWyzIpW7SVQn", ) -# The first key will be used to encrypt all new data, and decryption of existing values will be attempted -# with all given keys in order. This is useful for key rotation: place a new key at the head of the list -# for use with all new or changed data, but existing values encrypted with old keys will still be accessible -FERNET_KEYS = [ - env( - "FERNET_SECRET_KEY_1", - default="c1a70768d2e913ecc107963b307d1e2c6e4b78cc46f856c50caf035e4467adfa", - ) -] + # https://docs.djangoproject.com/en/dev/ref/settings/#test-runner TEST_RUNNER = "django.test.runner.DiscoverRunner" diff --git a/pyproject.toml b/pyproject.toml index a6ae114982..4078b64b0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,6 @@ known_third_party = [ "drf_yasg", "dry_rest_permissions", "environ", - "fernet_fields", "freezegun", "hardcopy", "healthy_django", diff --git a/requirements/base.txt b/requirements/base.txt index 8be91c1008..7a260b1abf 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,7 +22,6 @@ drf-nested-routers==0.91 django-multiselectfield==0.1.12 # https://github.com/goinnn/django-multiselectfield django-simple-history==2.8.0 # https://django-simple-history.readthedocs.io/en/latest/quick_start.html django-ratelimit==2.0.0 # Limiting Requests -django-fernet-fields==0.6 # https://django-fernet-fields.readthedocs.io/en/latest/ dry-rest-permissions==0.1.10 # For permissions handling django-cors-headers==3.2.1 django-watchman==1.1.0 # For Status Endpoints From 5907f29ed4af92d308834c38cb3ce664f26ce18a Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Wed, 14 Jun 2023 16:15:45 +0530 Subject: [PATCH 09/24] update django and related dependencies --- .flake8 | 1 + .../migrations/0004_alter_site_options.py | 20 + .../api/serializers/patient_consultation.py | 15 + care/facility/api/serializers/patient_otp.py | 5 +- care/facility/api/viewsets/asset.py | 14 +- care/facility/api/viewsets/notification.py | 6 +- .../api/viewsets/patient_consultation.py | 44 +- .../api/viewsets/patient_investigation.py | 16 +- care/facility/apps.py | 2 +- .../migrations/0001_initial_squashed.py | 5 +- ...oricalfacilitycapacity_options_and_more.py | 900 ++++++++++++++++++ care/facility/models/asset.py | 3 +- care/facility/models/bed.py | 2 +- care/facility/models/daily_round.py | 9 +- care/facility/models/facility.py | 8 +- care/facility/models/notification.py | 2 +- care/facility/models/patient.py | 4 +- care/facility/models/patient_consultation.py | 14 +- .../models/patient_tele_consultation.py | 5 +- care/facility/models/prescription.py | 2 +- care/facility/models/summary.py | 2 +- care/hcx/api/viewsets/gateway.py | 12 +- care/hcx/api/viewsets/listener.py | 8 +- care/hcx/apps.py | 2 +- ...im_id_alter_claim_items_alter_policy_id.py | 56 ++ care/hcx/models/claim.py | 2 +- care/users/api/viewsets/users.py | 25 +- care/users/forms.py | 2 +- ...er_localbody_id_alter_skill_id_and_more.py | 81 ++ care/users/models.py | 5 +- care/users/reset_password_views.py | 2 +- care/utils/models/jsonfield.py | 60 -- care/utils/schema.py | 8 + config/adminlogin.py | 2 +- config/api_router.py | 20 +- config/asgi.py | 40 + config/auth_views.py | 2 +- config/patient_otp_authentication.py | 2 +- config/ratelimit.py | 2 +- config/settings/base.py | 362 +++---- config/settings/deployment.py | 59 +- config/settings/local.py | 58 -- config/settings/test.py | 6 - config/urls.py | 48 +- config/validators.py | 2 +- config/websocket.py | 13 + config/wsgi.py | 9 +- data/dummy/facility.json | 1 - pyproject.toml | 2 +- requirements/base.txt | 90 +- requirements/local.txt | 37 +- requirements/production.txt | 9 +- 52 files changed, 1535 insertions(+), 571 deletions(-) create mode 100644 care/contrib/sites/migrations/0004_alter_site_options.py create mode 100644 care/facility/migrations/0004_alter_historicalfacilitycapacity_options_and_more.py create mode 100644 care/hcx/migrations/0002_alter_claim_id_alter_claim_items_alter_policy_id.py create mode 100644 care/users/migrations/0004_alter_district_id_alter_localbody_id_alter_skill_id_and_more.py delete mode 100644 care/utils/models/jsonfield.py create mode 100644 care/utils/schema.py create mode 100644 config/asgi.py create mode 100644 config/websocket.py diff --git a/.flake8 b/.flake8 index bee71452b9..25f2b30205 100644 --- a/.flake8 +++ b/.flake8 @@ -9,5 +9,6 @@ exclude = __pycache__, .venv, */migrations/*, + */migrations_old/*, */static/CACHE/*, docs diff --git a/care/contrib/sites/migrations/0004_alter_site_options.py b/care/contrib/sites/migrations/0004_alter_site_options.py new file mode 100644 index 0000000000..3d165b1073 --- /dev/null +++ b/care/contrib/sites/migrations/0004_alter_site_options.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.2 on 2023-06-14 08:36 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("sites", "0003_set_site_domain_and_name"), + ] + + operations = [ + migrations.AlterModelOptions( + name="site", + options={ + "ordering": ["domain"], + "verbose_name": "site", + "verbose_name_plural": "sites", + }, + ), + ] diff --git a/care/facility/api/serializers/patient_consultation.py b/care/facility/api/serializers/patient_consultation.py index 49872139d1..be74cff48d 100644 --- a/care/facility/api/serializers/patient_consultation.py +++ b/care/facility/api/serializers/patient_consultation.py @@ -465,3 +465,18 @@ class PatientConsultationIDSerializer(serializers.ModelSerializer): class Meta: model = PatientConsultation fields = ("consultation_id", "patient_id") + + +class EmailDischargeSummarySerializer(serializers.Serializer): + email = serializers.EmailField( + required=False, + help_text=( + "Email address to send the discharge summary to. If not provided, " + "the email address of the current user will be used." + ), + ) + + def validate(self, attrs): + if not attrs.get("email"): + attrs["email"] = self.context["request"].user.email + return attrs diff --git a/care/facility/api/serializers/patient_otp.py b/care/facility/api/serializers/patient_otp.py index 0eda6eba7d..9d6951e883 100644 --- a/care/facility/api/serializers/patient_otp.py +++ b/care/facility/api/serializers/patient_otp.py @@ -25,8 +25,9 @@ def send_sms(otp, phone_number): if settings.USE_SMS: sendSMS( phone_number, - "CoronaSafe Network Patient Management System Login, OTP is {} . Please do not share this Confidential Login Token with anyone else".format( - otp + ( + f"CoronaSafe Network Patient Management System Login, OTP is {otp} . " + "Please do not share this Confidential Login Token with anyone else" ), ) else: diff --git a/care/facility/api/viewsets/asset.py b/care/facility/api/viewsets/asset.py index c1b28f5ab0..2196b2e28d 100644 --- a/care/facility/api/viewsets/asset.py +++ b/care/facility/api/viewsets/asset.py @@ -5,7 +5,7 @@ from django.http import Http404 from django.shortcuts import get_object_or_404 from django_filters import rest_framework as filters -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissions from rest_framework import exceptions from rest_framework import filters as drf_filters @@ -179,7 +179,7 @@ def destroy(self, request, *args, **kwargs): "Only District Admin and above can delete assets" ) - @swagger_auto_schema(responses={200: UserDefaultAssetLocationSerializer()}) + @extend_schema(responses={200: UserDefaultAssetLocationSerializer()}) @action(detail=False, methods=["GET"]) def get_default_user_location(self, request, *args, **kwargs): obj = get_object_or_404( @@ -190,8 +190,8 @@ def get_default_user_location(self, request, *args, **kwargs): class DummyAssetSerializer(Serializer): # Dummy for Spec location = UUIDField(required=True) - @swagger_auto_schema( - request_body=DummyAssetSerializer, + @extend_schema( + request=DummyAssetSerializer, responses={200: UserDefaultAssetLocationSerializer()}, ) @action(detail=False, methods=["POST"]) @@ -238,8 +238,8 @@ class DummyAssetOperateResponseSerializer(Serializer): result = JSONField(required=False) # Asset Integration API - @swagger_auto_schema( - request_body=DummyAssetOperateSerializer, + @extend_schema( + request=DummyAssetOperateSerializer, responses={200: DummyAssetOperateResponseSerializer}, ) @action(detail=True, methods=["POST"]) @@ -264,7 +264,7 @@ def operate_assets(self, request, *args, **kwargs): except KeyError as e: return Response( - {"message": dict((key, "is required") for key in e.args)}, + {"message": {key: "is required" for key in e.args}}, status=status.HTTP_400_BAD_REQUEST, ) diff --git a/care/facility/api/viewsets/notification.py b/care/facility/api/viewsets/notification.py index f9bda01fa7..0f608c826d 100644 --- a/care/facility/api/viewsets/notification.py +++ b/care/facility/api/viewsets/notification.py @@ -1,6 +1,6 @@ from django.conf import settings from django_filters import rest_framework as filters -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from rest_framework import status from rest_framework.decorators import action from rest_framework.exceptions import ValidationError @@ -56,8 +56,8 @@ class DummyNotificationSerializer(Serializer): # Dummy for Spec facility = UUIDField(required=True) message = CharField(required=True) - @swagger_auto_schema( - request_body=DummyNotificationSerializer, + @extend_schema( + request=DummyNotificationSerializer, responses={204: "Notification Processed"}, ) @action(detail=False, methods=["POST"]) diff --git a/care/facility/api/viewsets/patient_consultation.py b/care/facility/api/viewsets/patient_consultation.py index 19a7cc70e9..8f5d96dc16 100644 --- a/care/facility/api/viewsets/patient_consultation.py +++ b/care/facility/api/viewsets/patient_consultation.py @@ -1,8 +1,6 @@ -from django.core.validators import validate_email from django.db.models.query_utils import Q from django_filters import rest_framework as filters -from drf_yasg import openapi -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissions from rest_framework import mixins, status from rest_framework.decorators import action @@ -13,6 +11,7 @@ from care.facility.api.serializers.file_upload import FileUploadRetrieveSerializer from care.facility.api.serializers.patient_consultation import ( + EmailDischargeSummarySerializer, PatientConsultationDischargeSerializer, PatientConsultationIDSerializer, PatientConsultationSerializer, @@ -59,6 +58,8 @@ def get_serializer_class(self): return PatientConsultationIDSerializer elif self.action == "discharge_patient": return PatientConsultationDischargeSerializer + elif self.action == "email_discharge_summary": + return EmailDischargeSummarySerializer else: return self.serializer_class @@ -93,8 +94,8 @@ def discharge_patient(self, request, *args, **kwargs): generate_and_upload_discharge_summary_task.delay(consultation.external_id) return Response(status=status.HTTP_200_OK) - @swagger_auto_schema( - operation_description="Generate a discharge summary", + @extend_schema( + description="Generate a discharge summary", responses={ 200: "Success", }, @@ -106,8 +107,8 @@ def generate_discharge_summary(self, request, *args, **kwargs): generate_and_upload_discharge_summary_task.delay(consultation.external_id) return Response({}) - @swagger_auto_schema( - operation_description="Get the discharge summary", + @extend_schema( + description="Get the discharge summary", responses={ 200: "Success", }, @@ -129,34 +130,25 @@ def preview_discharge_summary(self, request, *args, **kwargs): "Discharge summary is not ready yet. Please wait if a request has been placed." ) - @swagger_auto_schema( - operation_description="Email the discharge summary to the user", - request_body=openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - "email": openapi.Schema( - type=openapi.TYPE_STRING, description="Email address" - ) - }, - required=["email"], - ), + @extend_schema( + description="Email the discharge summary to the user", + request=EmailDischargeSummarySerializer, responses={200: "Success"}, ) @action(detail=True, methods=["POST"]) def email_discharge_summary(self, request, *args, **kwargs): consultation = self.get_object() - email = request.data.get("email", "") - try: - validate_email(email) - except Exception: - email = request.user.email + serializer = self.get_serializer( + data=request.data, context={"request": request} + ) + serializer.is_valid(raise_exception=True) + + email = serializer.validated_data["email"] email_discharge_summary.delay(consultation.external_id, email) return Response(status=status.HTTP_200_OK) - @swagger_auto_schema( - responses={200: PatientConsultationIDSerializer}, - ) + @extend_schema(responses={200: PatientConsultationIDSerializer}) @action(detail=False, methods=["GET"]) def patient_from_asset(self, request): consultation = ( diff --git a/care/facility/api/viewsets/patient_investigation.py b/care/facility/api/viewsets/patient_investigation.py index a0cc4de77f..e24c839955 100644 --- a/care/facility/api/viewsets/patient_investigation.py +++ b/care/facility/api/viewsets/patient_investigation.py @@ -1,9 +1,11 @@ +import contextlib + from django.db import transaction from django.db.models import F from django.db.models.query_utils import Q from django_filters import Filter from django_filters import rest_framework as filters -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from rest_framework import mixins, serializers, status, viewsets from rest_framework.decorators import action from rest_framework.exceptions import ValidationError @@ -107,10 +109,8 @@ class PatientInvestigationSummaryViewSet( def get_queryset(self): session_page = self.request.GET.get("session_page", 1) - try: + with contextlib.suppress(ValueError): session_page = int(session_page) - except ValueError: - pass investigations = self.request.GET.get("investigations", "") queryset = self.queryset.filter( consultation__patient__external_id=self.kwargs.get("patient_external_id") @@ -188,9 +188,7 @@ def get_queryset(self): filters |= Q(consultation__patient__assigned_to=self.request.user) return queryset.filter(filters).distinct("id") - @swagger_auto_schema( - responses={200: PatientInvestigationSessionSerializer(many=True)} - ) + @extend_schema(responses={200: PatientInvestigationSessionSerializer(many=True)}) @action(detail=False, methods=["GET"]) def get_sessions(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) @@ -213,8 +211,8 @@ class Meta: investigations = ValueSerializer(many=True) - @swagger_auto_schema( - request_body=InvestigationUpdateSerializer, + @extend_schema( + request=InvestigationUpdateSerializer, responses={204: "Operation successful"}, ) @action(detail=False, methods=["PUT"]) diff --git a/care/facility/apps.py b/care/facility/apps.py index f8647f11c2..14abcf74f7 100644 --- a/care/facility/apps.py +++ b/care/facility/apps.py @@ -3,7 +3,7 @@ class FacilityConfig(AppConfig): - name = "facility" + name = "care.facility" verbose_name = _("Facility Management") def ready(self): diff --git a/care/facility/migrations/0001_initial_squashed.py b/care/facility/migrations/0001_initial_squashed.py index 35ac30edb2..0917e3e324 100644 --- a/care/facility/migrations/0001_initial_squashed.py +++ b/care/facility/migrations/0001_initial_squashed.py @@ -15,7 +15,6 @@ import care.facility.models.mixins.permissions.asset import care.facility.models.mixins.permissions.facility import care.facility.models.mixins.permissions.patient -import care.utils.models.jsonfield import care.utils.models.validators @@ -2920,7 +2919,7 @@ class Migration(migrations.Migration): ), ( "countries_travelled", - care.utils.models.jsonfield.JSONField( + django.contrib.postgres.fields.JSONField( blank=True, null=True, verbose_name="Countries Patient has Travelled to", @@ -5283,7 +5282,7 @@ class Migration(migrations.Migration): ), ( "countries_travelled", - care.utils.models.jsonfield.JSONField( + django.contrib.postgres.fields.JSONField( blank=True, null=True, verbose_name="Countries Patient has Travelled to", diff --git a/care/facility/migrations/0004_alter_historicalfacilitycapacity_options_and_more.py b/care/facility/migrations/0004_alter_historicalfacilitycapacity_options_and_more.py new file mode 100644 index 0000000000..09481fc620 --- /dev/null +++ b/care/facility/migrations/0004_alter_historicalfacilitycapacity_options_and_more.py @@ -0,0 +1,900 @@ +# Generated by Django 4.2.2 on 2023-06-14 08:36 + +import django.contrib.postgres.fields +from django.db import migrations, models + +import care.utils.models.validators + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0003_auto_20230614_1048"), + ] + + operations = [ + migrations.AlterModelOptions( + name="historicalfacilitycapacity", + options={ + "get_latest_by": ("history_date", "history_id"), + "ordering": ("-history_date", "-history_id"), + "verbose_name": "historical facility capacity", + "verbose_name_plural": "historical Facility Capacities", + }, + ), + migrations.AlterModelOptions( + name="historicalpatientregistration", + options={ + "get_latest_by": ("history_date", "history_id"), + "ordering": ("-history_date", "-history_id"), + "verbose_name": "historical patient registration", + "verbose_name_plural": "historical patient registrations", + }, + ), + migrations.AlterField( + model_name="ambulance", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="ambulancedriver", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="asset", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="asset", + name="meta", + field=models.JSONField( + blank=True, + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + {"$ref": "#/definitions/onvif"}, + {"$ref": "#/definitions/hl7monitor"}, + {"$ref": "#/definitions/empty"}, + ], + "definitions": { + "empty": { + "additionalProperties": False, + "type": "object", + }, + "hl7monitor": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + }, + "required": ["local_ip_address"], + "type": "object", + }, + "onvif": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "camera_access_key": {"type": "string"}, + "camera_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + }, + "required": [ + "local_ip_address", + "camera_access_key", + ], + "type": "object", + }, + "ventilator": { + "additionalProperties": False, + "properties": { + "asset_type": {"type": "string"}, + "insecure_connection": {"type": "boolean"}, + "local_ip_address": {"type": "string"}, + "middleware_hostname": {"type": "string"}, + }, + "required": ["local_ip_address"], + "type": "object", + }, + }, + } + ) + ], + ), + ), + migrations.AlterField( + model_name="assetbed", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="assetbed", + name="meta", + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name="assetlocation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="assettransaction", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="bed", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="bed", + name="meta", + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name="building", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="consultationbed", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="consultationbed", + name="meta", + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name="dailyround", + name="bp", + field=models.JSONField( + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": False, + "properties": { + "diastolic": {"type": "number"}, + "mean": {"type": "number"}, + "systolic": {"type": "number"}, + }, + "type": "object", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="feeds", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "calories": {"type": "number"}, + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="dailyround", + name="infusions", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "conc_unit": {"type": "string"}, + "concentration": {"type": "number"}, + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="iv_fluids", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="medication_given", + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name="dailyround", + name="medicine_administration", + field=models.JSONField(default=list), + ), + migrations.AlterField( + model_name="dailyround", + name="meta", + field=models.JSONField( + default=dict, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": False, + "properties": {"dialysis": {"type": "boolean"}}, + "type": "object", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="nursing", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "procedure": {"type": "string"}, + }, + "required": ["procedure", "description"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="output", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "name": {"type": "string"}, + "quantity": {"type": "number"}, + }, + "required": ["name", "quantity"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="pain_scale_enhanced", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "description": {"type": "string"}, + "region": {"type": "string"}, + "scale": { + "maximum": 5, + "minimum": 1, + "type": "number", + }, + }, + "required": ["region", "scale"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="dailyround", + name="pressure_sore", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "base_score": {"type": "number"}, + "description": {"type": "string"}, + "exudate_amount": { + "enum": [ + "None", + "Light", + "Moderate", + "Heavy", + ] + }, + "length": {"type": "number"}, + "push_score": {"type": "number"}, + "region": {"type": "string"}, + "scale": { + "maximum": 5, + "minimum": 1, + "type": "number", + }, + "tissue_type": { + "enum": [ + "Closed", + "Epithelial", + "Granulation", + "Slough", + "Necrotic", + ] + }, + "width": {"type": "number"}, + }, + "required": [], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="disease", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="districtscopedsummary", + name="data", + field=models.JSONField(blank=True, default=dict, null=True), + ), + migrations.AlterField( + model_name="facility", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilitycapacity", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilitydefaultassetlocation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventoryburnrate", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventoryitem", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventoryitemtag", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventorylog", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventoryminquantity", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventorysummary", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventoryunit", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityinventoryunitconverter", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilitylocalgovtbody", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilitypatientstatshistory", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityrelatedsummary", + name="data", + field=models.JSONField(blank=True, default=dict, null=True), + ), + migrations.AlterField( + model_name="facilitystaff", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityuser", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="facilityvolunteer", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="fileupload", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="historicalfacilitycapacity", + name="history_date", + field=models.DateTimeField(db_index=True), + ), + migrations.AlterField( + model_name="historicalfacilitycapacity", + name="id", + field=models.BigIntegerField( + auto_created=True, blank=True, db_index=True, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="historicalpatientregistration", + name="countries_travelled", + field=models.JSONField( + blank=True, null=True, verbose_name="Countries Patient has Travelled to" + ), + ), + migrations.AlterField( + model_name="historicalpatientregistration", + name="history_date", + field=models.DateTimeField(db_index=True), + ), + migrations.AlterField( + model_name="historicalpatientregistration", + name="id", + field=models.BigIntegerField( + auto_created=True, blank=True, db_index=True, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="hospitaldoctors", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="inventory", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="inventoryitem", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="inventorylog", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="investigationsession", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="investigationvalue", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="localbodyscopedsummary", + name="data", + field=models.JSONField(blank=True, default=dict, null=True), + ), + migrations.AlterField( + model_name="medicineadministration", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="notification", + name="caused_objects", + field=models.JSONField(blank=True, default=dict, null=True), + ), + migrations.AlterField( + model_name="notification", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientconsultation", + name="discharge_advice", + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name="patientconsultation", + name="discharge_prescription", + field=models.JSONField(blank=True, default=dict, null=True), + ), + migrations.AlterField( + model_name="patientconsultation", + name="discharge_prn_prescription", + field=models.JSONField(blank=True, default=dict, null=True), + ), + migrations.AlterField( + model_name="patientconsultation", + name="icd11_diagnoses", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(max_length=100), + blank=True, + default=list, + null=True, + size=None, + ), + ), + migrations.AlterField( + model_name="patientconsultation", + name="icd11_provisional_diagnoses", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(max_length=100), + blank=True, + default=list, + null=True, + size=None, + ), + ), + migrations.AlterField( + model_name="patientconsultation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientconsultation", + name="intubation_history", + field=models.JSONField(default=list), + ), + migrations.AlterField( + model_name="patientconsultation", + name="investigation", + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name="patientconsultation", + name="prescriptions", + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name="patientconsultation", + name="prn_prescription", + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name="patientconsultation", + name="procedure", + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name="patientcontactdetails", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientexternaltest", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientinvestigation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientinvestigationgroup", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientmetainfo", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientmobileotp", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientnotes", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientregistration", + name="countries_travelled", + field=models.JSONField( + blank=True, null=True, verbose_name="Countries Patient has Travelled to" + ), + ), + migrations.AlterField( + model_name="patientregistration", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientsample", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientsampleflow", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="patientteleconsultation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="prescription", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="prescription", + name="meta", + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name="prescriptionsupplier", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="resourcerequest", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="resourcerequestcomment", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="room", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="shiftingrequest", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="shiftingrequestcomment", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="staffroomallocation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="userdefaultassetlocation", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ] diff --git a/care/facility/models/asset.py b/care/facility/models/asset.py index 95aabd9d08..ac14fba3a0 100644 --- a/care/facility/models/asset.py +++ b/care/facility/models/asset.py @@ -1,9 +1,8 @@ import enum import uuid -from django.contrib.postgres.fields.jsonb import JSONField from django.db import models -from django.db.models import Q +from django.db.models import JSONField, Q from care.facility.models.facility import Facility from care.facility.models.json_schema.asset import ASSET_META diff --git a/care/facility/models/bed.py b/care/facility/models/bed.py index ec581b94c9..3f055db8a8 100644 --- a/care/facility/models/bed.py +++ b/care/facility/models/bed.py @@ -4,9 +4,9 @@ However this is an addon feature and is not required for the regular patient flow, Leaving scope to build rooms and wards to being even more organization. """ -from django.contrib.postgres.fields.jsonb import JSONField from django.core.exceptions import ValidationError from django.db import models +from django.db.models import JSONField from care.facility.models.asset import Asset, AssetLocation from care.facility.models.facility import Facility diff --git a/care/facility/models/daily_round.py b/care/facility/models/daily_round.py index c957a0ac16..e9ead8c87d 100644 --- a/care/facility/models/daily_round.py +++ b/care/facility/models/daily_round.py @@ -1,10 +1,11 @@ import enum -from django.contrib.postgres.fields import JSONField from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models +from django.db.models import JSONField from django.shortcuts import get_object_or_404 from multiselectfield import MultiSelectField +from multiselectfield.utils import get_max_length from care.facility.models import ( CATEGORY_CHOICES, @@ -137,7 +138,11 @@ class InsulinIntakeFrequencyType(enum.Enum): temperature_measured_at = models.DateTimeField(null=True, blank=True) physical_examination_info = models.TextField(null=True, blank=True) additional_symptoms = MultiSelectField( - choices=SYMPTOM_CHOICES, default=1, null=True, blank=True + choices=SYMPTOM_CHOICES, + default=1, + null=True, + blank=True, + max_length=get_max_length(SYMPTOM_CHOICES, None), ) other_symptoms = models.TextField(default="", blank=True) deprecated_covid_category = models.CharField( diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index a407be8a63..327a310ee7 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -3,6 +3,7 @@ from django.core.validators import MinValueValidator from django.db import models from multiselectfield import MultiSelectField +from multiselectfield.utils import get_max_length from simple_history.models import HistoricalRecords from care.facility.models import FacilityBaseModel, phone_number_regex, reverse_choices @@ -114,7 +115,12 @@ class Facility(FacilityBaseModel, FacilityPermissionMixin): verified = models.BooleanField(default=False) facility_type = models.IntegerField(choices=FACILITY_TYPES) kasp_empanelled = models.BooleanField(default=False, blank=False, null=False) - features = MultiSelectField(choices=FEATURE_CHOICES, null=True, blank=True) + features = MultiSelectField( + choices=FEATURE_CHOICES, + null=True, + blank=True, + max_length=get_max_length(FEATURE_CHOICES, None), + ) longitude = models.DecimalField( max_digits=22, decimal_places=16, null=True, blank=True diff --git a/care/facility/models/notification.py b/care/facility/models/notification.py index a43b1a4cb8..de2b1d59d8 100644 --- a/care/facility/models/notification.py +++ b/care/facility/models/notification.py @@ -1,7 +1,7 @@ import enum -from django.contrib.postgres.fields import JSONField from django.db import models +from django.db.models import JSONField from care.facility.models import FacilityBaseModel from care.users.models import User diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index b9ffff2cd6..54582cc83c 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -3,6 +3,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models +from django.db.models import JSONField from simple_history.models import HistoricalRecords from care.facility.models import ( @@ -39,7 +40,6 @@ phone_number_regex, ) from care.utils.models.base import BaseManager, BaseModel -from care.utils.models.jsonfield import JSONField class PatientRegistration(PatientBaseModel, PatientPermissionMixin): @@ -410,7 +410,7 @@ class TestTypeEnum(enum.Enum): related_name="root_patient_assigned_to", ) - history = HistoricalRecords(excluded_fields=["patient_search_id", "meta_info"]) + history = HistoricalRecords(excluded_fields=["meta_info"]) objects = BaseManager() diff --git a/care/facility/models/patient_consultation.py b/care/facility/models/patient_consultation.py index aedbe58a65..de097a16ce 100644 --- a/care/facility/models/patient_consultation.py +++ b/care/facility/models/patient_consultation.py @@ -1,7 +1,9 @@ -from django.contrib.postgres.fields import ArrayField, JSONField +from django.contrib.postgres.fields import ArrayField from django.core.validators import MinValueValidator from django.db import models +from django.db.models import JSONField from multiselectfield import MultiSelectField +from multiselectfield.utils import get_max_length from care.facility.models import ( CATEGORY_CHOICES, @@ -49,13 +51,17 @@ class PatientConsultation(PatientBaseModel, PatientRelatedPermissionMixin): ) diagnosis = models.TextField(default="", null=True, blank=True) # Deprecated icd11_provisional_diagnoses = ArrayField( - models.CharField(max_length=100), default=[], blank=True, null=True + models.CharField(max_length=100), default=list, blank=True, null=True ) icd11_diagnoses = ArrayField( - models.CharField(max_length=100), default=[], blank=True, null=True + models.CharField(max_length=100), default=list, blank=True, null=True ) symptoms = MultiSelectField( - choices=SYMPTOM_CHOICES, default=1, null=True, blank=True + choices=SYMPTOM_CHOICES, + default=1, + null=True, + blank=True, + max_length=get_max_length(SYMPTOM_CHOICES, None), ) other_symptoms = models.TextField(default="", blank=True) symptoms_onset_date = models.DateTimeField(null=True, blank=True) diff --git a/care/facility/models/patient_tele_consultation.py b/care/facility/models/patient_tele_consultation.py index 14e4be1111..148af50990 100644 --- a/care/facility/models/patient_tele_consultation.py +++ b/care/facility/models/patient_tele_consultation.py @@ -1,5 +1,6 @@ from django.db import models from multiselectfield import MultiSelectField +from multiselectfield.utils import get_max_length from care.facility.models import SYMPTOM_CHOICES, PatientRegistration from care.users.models import User @@ -7,7 +8,9 @@ class PatientTeleConsultation(models.Model): patient = models.ForeignKey(PatientRegistration, on_delete=models.PROTECT) - symptoms = MultiSelectField(choices=SYMPTOM_CHOICES) + symptoms = MultiSelectField( + choices=SYMPTOM_CHOICES, max_length=get_max_length(SYMPTOM_CHOICES, None) + ) other_symptoms = models.TextField(blank=True, null=True) reason = models.TextField(blank=True, null=True, verbose_name="Reason for calling") created_date = models.DateTimeField(auto_now_add=True) diff --git a/care/facility/models/prescription.py b/care/facility/models/prescription.py index 1ee0cb3b9d..65bd2f621b 100644 --- a/care/facility/models/prescription.py +++ b/care/facility/models/prescription.py @@ -1,8 +1,8 @@ import enum -from django.contrib.postgres.fields.jsonb import JSONField from django.core.exceptions import ValidationError from django.db import models +from django.db.models import JSONField from django.utils import timezone from care.facility.models.patient_consultation import PatientConsultation diff --git a/care/facility/models/summary.py b/care/facility/models/summary.py index fd56a628f6..5579bc564d 100644 --- a/care/facility/models/summary.py +++ b/care/facility/models/summary.py @@ -1,7 +1,7 @@ from uuid import uuid4 -from django.contrib.postgres.fields import JSONField from django.db import models +from django.db.models import JSONField from care.facility.models.facility import Facility from care.users.models import District, LocalBody diff --git a/care/hcx/api/viewsets/gateway.py b/care/hcx/api/viewsets/gateway.py index e1cb7e88c7..4c4651803e 100644 --- a/care/hcx/api/viewsets/gateway.py +++ b/care/hcx/api/viewsets/gateway.py @@ -4,7 +4,7 @@ from uuid import uuid4 as uuid from django.db.models import Q -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from rest_framework import status from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated @@ -41,7 +41,7 @@ class HcxGatewayViewSet(GenericViewSet): queryset = Policy.objects.all() permission_classes = (IsAuthenticated,) - @swagger_auto_schema(tags=["hcx"], request_body=CheckEligibilitySerializer()) + @extend_schema(tags=["hcx"], request=CheckEligibilitySerializer()) @action(detail=False, methods=["post"]) def check_eligibility(self, request): data = request.data @@ -98,7 +98,7 @@ def check_eligibility(self, request): return Response(dict(response.get("response")), status=status.HTTP_200_OK) - @swagger_auto_schema(tags=["hcx"], request_body=MakeClaimSerializer()) + @extend_schema(tags=["hcx"], request=MakeClaimSerializer()) @action(detail=False, methods=["post"]) def make_claim(self, request): data = request.data @@ -261,7 +261,7 @@ def make_claim(self, request): return Response(dict(response.get("response")), status=status.HTTP_200_OK) - @swagger_auto_schema(tags=["hcx"]) + @extend_schema(tags=["hcx"]) @action(detail=False, methods=["get"]) def payors(self, request): payors = Hcx().searchRegistry("roles", "payor")["participants"] @@ -280,7 +280,7 @@ def payors(self, request): return Response(response, status=status.HTTP_200_OK) - @swagger_auto_schema(tags=["hcx"]) + @extend_schema(tags=["hcx"]) @action(detail=False, methods=["get"]) def pmjy_packages(self, request): from care.hcx.static_data.pmjy_packages import PMJYPackages @@ -310,4 +310,4 @@ def serailize_data(pmjy_packages): or search(r".*" + query + r".*", row.package_name, IGNORECASE) is not None ) - return Response(serailize_data(queryset[0:limit])) + return Response(serailize_data(queryset[:limit])) diff --git a/care/hcx/api/viewsets/listener.py b/care/hcx/api/viewsets/listener.py index 8927fa11ba..1da9cb3f2d 100644 --- a/care/hcx/api/viewsets/listener.py +++ b/care/hcx/api/viewsets/listener.py @@ -1,6 +1,6 @@ import json -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from rest_framework import status from rest_framework.generics import GenericAPIView from rest_framework.permissions import AllowAny @@ -17,7 +17,7 @@ class CoverageElibilityOnCheckView(GenericAPIView): permission_classes = (AllowAny,) authentication_classes = [] - @swagger_auto_schema(tags=["hcx"]) + @extend_schema(tags=["hcx"]) def post(self, request, *args, **kwargs): response = Hcx().processIncomingRequest(request.data["payload"]) data = Fhir().process_coverage_elibility_check_response(response["payload"]) @@ -43,7 +43,7 @@ class PreAuthOnSubmitView(GenericAPIView): permission_classes = (AllowAny,) authentication_classes = [] - @swagger_auto_schema(tags=["hcx"]) + @extend_schema(tags=["hcx"]) def post(self, request, *args, **kwargs): response = Hcx().processIncomingRequest(request.data["payload"]) data = Fhir().process_claim_response(response["payload"]) @@ -70,7 +70,7 @@ class ClaimOnSubmitView(GenericAPIView): permission_classes = (AllowAny,) authentication_classes = [] - @swagger_auto_schema(tags=["hcx"]) + @extend_schema(tags=["hcx"]) def post(self, request, *args, **kwargs): response = Hcx().processIncomingRequest(request.data["payload"]) data = Fhir().process_claim_response(response["payload"]) diff --git a/care/hcx/apps.py b/care/hcx/apps.py index 4f6345e5b6..5b4da22bd7 100644 --- a/care/hcx/apps.py +++ b/care/hcx/apps.py @@ -3,5 +3,5 @@ class HcxConfig(AppConfig): - name = "hcx" + name = "care.hcx" verbose_name = _("HCX Integration") diff --git a/care/hcx/migrations/0002_alter_claim_id_alter_claim_items_alter_policy_id.py b/care/hcx/migrations/0002_alter_claim_id_alter_claim_items_alter_policy_id.py new file mode 100644 index 0000000000..6f39c8479a --- /dev/null +++ b/care/hcx/migrations/0002_alter_claim_id_alter_claim_items_alter_policy_id.py @@ -0,0 +1,56 @@ +# Generated by Django 4.2.2 on 2023-06-14 08:36 + +from django.db import migrations, models + +import care.utils.models.validators + + +class Migration(migrations.Migration): + dependencies = [ + ("hcx", "0001_initial_squashed"), + ] + + operations = [ + migrations.AlterField( + model_name="claim", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="claim", + name="items", + field=models.JSONField( + default=list, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "items": [ + { + "additionalProperties": False, + "properties": { + "category": {"type": "string"}, + "id": {"type": "string"}, + "name": {"type": "string"}, + "price": {"type": "number"}, + }, + "required": ["id", "name", "price"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="policy", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ] diff --git a/care/hcx/models/claim.py b/care/hcx/models/claim.py index 8eeb3810ba..6334e258c0 100644 --- a/care/hcx/models/claim.py +++ b/care/hcx/models/claim.py @@ -1,5 +1,5 @@ -from django.contrib.postgres.fields import JSONField from django.db import models +from django.db.models import JSONField from care.facility.models.patient import PatientConsultation from care.hcx.models.base import ( diff --git a/care/users/api/viewsets/users.py b/care/users/api/viewsets/users.py index 96d9457e06..ec35bf1d00 100644 --- a/care/users/api/viewsets/users.py +++ b/care/users/api/viewsets/users.py @@ -2,8 +2,7 @@ from django.core.cache import cache from django.db.models import F from django_filters import rest_framework as filters -from drf_yasg import openapi -from drf_yasg.utils import swagger_auto_schema +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissions from rest_framework import filters as drf_filters from rest_framework import filters as rest_framework_filters @@ -29,7 +28,7 @@ def remove_facility_user_cache(user_id): - key = "user_facilities:" + str(user_id) + key = f"user_facilities:{str(user_id)}" cache.delete(key) return True @@ -241,23 +240,9 @@ def add_facility(self, request, *args, **kwargs): FacilityUser(facility=facility, user=user, created_by=requesting_user).save() return Response(status=status.HTTP_201_CREATED) - @swagger_auto_schema( - method="delete", - request_body=openapi.Schema( - type=openapi.TYPE_OBJECT, - required=["facility"], - title="Facility", - properties={ - "facility": openapi.Schema( - type=openapi.TYPE_STRING, - format=openapi.FORMAT_UUID, - title="Facility External ID", - ) - }, - ), - responses={ - 204: "Deleted Successfully", - }, + @extend_schema( + request=None, + responses={204: "Deleted Successfully"}, ) @action(detail=True, methods=["DELETE"], permission_classes=[IsAuthenticated]) def clear_home_facility(self, request, *args, **kwargs): diff --git a/care/users/forms.py b/care/users/forms.py index c0bcb3b260..cf4b25a56a 100644 --- a/care/users/forms.py +++ b/care/users/forms.py @@ -1,6 +1,6 @@ from django.contrib.auth import forms, get_user_model from django.core.exceptions import ValidationError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ User = get_user_model() diff --git a/care/users/migrations/0004_alter_district_id_alter_localbody_id_alter_skill_id_and_more.py b/care/users/migrations/0004_alter_district_id_alter_localbody_id_alter_skill_id_and_more.py new file mode 100644 index 0000000000..52feb6f125 --- /dev/null +++ b/care/users/migrations/0004_alter_district_id_alter_localbody_id_alter_skill_id_and_more.py @@ -0,0 +1,81 @@ +# Generated by Django 4.2.2 on 2023-06-14 08:36 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0004_alter_historicalfacilitycapacity_options_and_more"), + ("users", "0003_auto_20230613_1657"), + ] + + operations = [ + migrations.AlterField( + model_name="district", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="localbody", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="skill", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="state", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="user", + name="asset", + field=models.OneToOneField( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="facility.asset", + ), + ), + migrations.AlterField( + model_name="user", + name="first_name", + field=models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + migrations.AlterField( + model_name="user", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="userskill", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="ward", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ] diff --git a/care/users/models.py b/care/users/models.py index 741609f016..d4068ffd99 100644 --- a/care/users/models.py +++ b/care/users/models.py @@ -5,7 +5,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator from django.db import models from django.urls import reverse -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from care.utils.models.base import BaseModel @@ -270,13 +270,12 @@ class User(AbstractUser): # Asset Fields - asset = models.ForeignKey( + asset = models.OneToOneField( "facility.Asset", default=None, null=True, blank=True, on_delete=models.PROTECT, - unique=True, ) objects = CustomUserManager() diff --git a/care/users/reset_password_views.py b/care/users/reset_password_views.py index 27fc5e7cf6..fc57cd781c 100644 --- a/care/users/reset_password_views.py +++ b/care/users/reset_password_views.py @@ -8,7 +8,7 @@ ) from django.core.exceptions import ValidationError from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django_rest_passwordreset.models import ( ResetPasswordToken, clear_expired, diff --git a/care/utils/models/jsonfield.py b/care/utils/models/jsonfield.py deleted file mode 100644 index 56d9cb4795..0000000000 --- a/care/utils/models/jsonfield.py +++ /dev/null @@ -1,60 +0,0 @@ -# Reference: https://medium.com/@philamersune/using-postgresql-jsonfield-in-sqlite-95ad4ad2e5f1 -import json - -from django.conf import settings -from django.contrib.postgres.fields import ArrayField as DjangoArrayField -from django.contrib.postgres.fields import JSONField as DjangoJSONField -from django.db.models import Field - -if "spatialite" in settings.DATABASES["default"]["ENGINE"]: - - class JSONField(Field): - def db_type(self, connection): - return "text" - - def from_db_value(self, value, expression, connection): - if value is not None: - return self.to_python(value) - return value - - def to_python(self, value): - if value is not None: - try: - return json.loads(value) - except (TypeError, ValueError): - return value - return value - - def get_prep_value(self, value): - if value is not None: - return str(json.dumps(value)) - return value - - def value_to_string(self, obj): - return self.value_from_object(obj) - - class ArrayField(JSONField): - def __init__(self, base_field, size=None, **kwargs): - """Care for DjangoArrayField's kwargs.""" - self.base_field = base_field - self.size = size - super().__init__(**kwargs) - - def deconstruct(self): - """Need to create migrations properly.""" - name, path, args, kwargs = super().deconstruct() - kwargs.update( - { - "base_field": self.base_field.clone(), - "size": self.size, - } - ) - return name, path, args, kwargs - -else: - - class JSONField(DjangoJSONField): - pass - - class ArrayField(DjangoArrayField): - pass diff --git a/care/utils/schema.py b/care/utils/schema.py new file mode 100644 index 0000000000..5b8813c1c1 --- /dev/null +++ b/care/utils/schema.py @@ -0,0 +1,8 @@ +from drf_spectacular.openapi import AutoSchema as SpectacularAutoSchema + + +class AutoSchema(SpectacularAutoSchema): + def get_tags(self): + tokenized_path = self._tokenize_path() + # use last non-parameter path part as default tag + return [tokenized_path[-1]] diff --git a/config/adminlogin.py b/config/adminlogin.py index 6189671ce6..56e9bb0957 100644 --- a/config/adminlogin.py +++ b/config/adminlogin.py @@ -1,7 +1,7 @@ from django.contrib import messages from django.shortcuts import redirect from django.urls import reverse -from ratelimit.decorators import ratelimit +from django_ratelimit.decorators import ratelimit def login_wrapper(login_func): diff --git a/config/api_router.py b/config/api_router.py index b01a03b668..83aed2b502 100644 --- a/config/api_router.py +++ b/config/api_router.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.conf.urls import include, url +from django.urls import include, path from rest_framework.routers import DefaultRouter, SimpleRouter from rest_framework_nested.routers import NestedSimpleRouter @@ -92,8 +92,8 @@ router = SimpleRouter() router.register("users", UserViewSet) -user_nested_rotuer = NestedSimpleRouter(router, r"users", lookup="users") -user_nested_rotuer.register("skill", UserSkillViewSet) +user_nested_router = NestedSimpleRouter(router, r"users", lookup="users") +user_nested_router.register("skill", UserSkillViewSet) router.register("skill", SkillViewSet) @@ -209,11 +209,11 @@ app_name = "api" urlpatterns = [ - url(r"^", include(router.urls)), - url(r"^", include(user_nested_rotuer.urls)), - url(r"^", include(facility_nested_router.urls)), - url(r"^", include(patient_nested_router.urls)), - url(r"^", include(consultation_nested_router.urls)), - url(r"^", include(resource_nested_router.urls)), - url(r"^", include(shifting_nested_router.urls)), + path("", include(router.urls)), + path("", include(user_nested_router.urls)), + path("", include(facility_nested_router.urls)), + path("", include(patient_nested_router.urls)), + path("", include(consultation_nested_router.urls)), + path("", include(resource_nested_router.urls)), + path("", include(shifting_nested_router.urls)), ] diff --git a/config/asgi.py b/config/asgi.py new file mode 100644 index 0000000000..724751777f --- /dev/null +++ b/config/asgi.py @@ -0,0 +1,40 @@ +""" +ASGI config for care project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/dev/howto/deployment/asgi/ + +""" +import os +import sys +from pathlib import Path + +from django.core.asgi import get_asgi_application + +# This allows easy placement of apps within the interior +# care directory. +BASE_DIR = Path(__file__).resolve(strict=True).parent.parent +sys.path.append(str(BASE_DIR / "care")) + +# If DJANGO_SETTINGS_MODULE is unset, default to the local settings +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") + +# This application object is used by any ASGI server configured to use this file. +django_application = get_asgi_application() +# Apply ASGI middleware here. +# from helloworld.asgi import HelloWorldApplication +# application = HelloWorldApplication(application) + +# Import websocket application here, so apps from django_application are loaded first +from config.websocket import websocket_application # noqa isort:skip + + +async def application(scope, receive, send): + if scope["type"] == "http": + await django_application(scope, receive, send) + elif scope["type"] == "websocket": + await websocket_application(scope, receive, send) + else: + raise NotImplementedError(f"Unknown scope type {scope['type']}") diff --git a/config/auth_views.py b/config/auth_views.py index eca7c55a54..ef2da9cbf2 100644 --- a/config/auth_views.py +++ b/config/auth_views.py @@ -1,6 +1,6 @@ from django.contrib.auth import authenticate, get_user_model from django.utils.timezone import localtime, now -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers, status from rest_framework_simplejwt.exceptions import AuthenticationFailed from rest_framework_simplejwt.serializers import PasswordField diff --git a/config/patient_otp_authentication.py b/config/patient_otp_authentication.py index d168ba7ce2..7bb558ac0c 100644 --- a/config/patient_otp_authentication.py +++ b/config/patient_otp_authentication.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework_simplejwt.authentication import JWTAuthentication from rest_framework_simplejwt.exceptions import InvalidToken, TokenError diff --git a/config/ratelimit.py b/config/ratelimit.py index 4d59c8dcf3..e6c66fb3c1 100644 --- a/config/ratelimit.py +++ b/config/ratelimit.py @@ -1,6 +1,6 @@ import requests from django.conf import settings -from ratelimit.utils import is_ratelimited +from django_ratelimit.core import is_ratelimited def validatecaptcha(request): diff --git a/config/settings/base.py b/config/settings/base.py index a547b3ffc0..6261f777df 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -5,6 +5,7 @@ import base64 import json from datetime import timedelta +from pathlib import Path import environ from authlib.jose import JsonWebKey @@ -14,20 +15,23 @@ from care.utils.csp import config as csp_config from care.utils.jwks.generate_jwk import generate_encoded_jwks -SILENCED_SYSTEM_CHECKS = ["postgres.E003", "fields.W342"] - -ROOT_DIR = environ.Path(__file__) - 3 # (care/config/settings/base.py - 3 = care/) -APPS_DIR = ROOT_DIR.path("care") - +BASE_DIR = Path(__file__).resolve(strict=True).parent.parent.parent +APPS_DIR = BASE_DIR / "care" env = environ.Env() -READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False) -if READ_DOT_ENV_FILE: +if READ_DOT_ENV_FILE := env.bool("DJANGO_READ_DOT_ENV_FILE", default=False): # OS environment variables take precedence over variables from .env - env.read_env(str(ROOT_DIR.path(".env"))) + env.read_env(str(BASE_DIR / ".env")) # GENERAL # ------------------------------------------------------------------------------ +# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key +SECRET_KEY = env( + "DJANGO_SECRET_KEY", + default="eXZQzOzx8gV38rDG0Z0fFZWweUGl3LwMZ9aTKqJiXQTI0nKMh0Z7sbHfqT8KFEnd", +) +# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts +ALLOWED_HOSTS = env.json("DJANGO_ALLOWED_HOSTS", default=["*"]) # https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = env.bool("DJANGO_DEBUG", False) # Local time zone. Choices are @@ -35,27 +39,41 @@ # though not all of them may be available with every OS. # In Windows, this must be set to your system time zone. TIME_ZONE = "Asia/Kolkata" - # https://docs.djangoproject.com/en/dev/ref/settings/#language-code LANGUAGE_CODE = "en-us" # https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 # https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n USE_I18N = True -# https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n -USE_L10N = True # https://docs.djangoproject.com/en/dev/ref/settings/#use-tz USE_TZ = True # https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths -LOCALE_PATHS = [ROOT_DIR.path("locale")] +LOCALE_PATHS = [str(BASE_DIR / "locale")] # DATABASES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#databases - DATABASES = {"default": env.db("DATABASE_URL", default="postgres:///care")} DATABASES["default"]["ATOMIC_REQUESTS"] = True DATABASES["default"]["CONN_MAX_AGE"] = 300 +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +# CACHES +# ------------------------------------------------------------------------------ +# https://docs.djangoproject.com/en/dev/ref/settings/#caches +CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": env("REDIS_URL", default="redis://localhost:6379"), + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + # Mimicing memcache behavior. + # http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior + "IGNORE_EXCEPTIONS": True, + }, + } +} + # URLS # ------------------------------------------------------------------------------ @@ -64,9 +82,6 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = "config.wsgi.application" -# CollectFast -# - # APPS # ------------------------------------------------------------------------------ DJANGO_APPS = [ @@ -83,24 +98,22 @@ "storages", "rest_framework", "rest_framework.authtoken", - "drf_yasg", + "drf_spectacular", "django_filters", "simple_history", - "ratelimit", + "django_ratelimit", "dry_rest_permissions", "corsheaders", - "watchman", "djangoql", "maintenance_mode", "django.contrib.postgres", "django_rest_passwordreset", "healthy_django", ] - LOCAL_APPS = [ - "care.users.apps.UsersConfig", + "care.users", "care.facility", - "care.audit_log.apps.AuditLogConfig", + "care.audit_log", "care.hcx", ] # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps @@ -122,6 +135,8 @@ LOGIN_REDIRECT_URL = "/" # https://docs.djangoproject.com/en/dev/ref/settings/#login-url LOGIN_URL = "/" +# https://docs.djangoproject.com/en/dev/ref/settings/#logout-redirect-url +LOGOUT_REDIRECT_URL = "/" # PASSWORDS # ------------------------------------------------------------------------------ @@ -165,26 +180,28 @@ # STATIC # ------------------------------------------------------------------------------ -USE_S3 = env.bool("USE_S3", default=False) - -if USE_S3: - # aws settings - AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID") - AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY") - AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME") - AWS_DEFAULT_ACL = "public-read" - AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com" - AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"} - +# https://docs.djangoproject.com/en/dev/ref/settings/#static-files +# https://docs.djangoproject.com/en/dev/ref/settings/#static-root +STATIC_ROOT = str(BASE_DIR / "staticfiles") +# https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = "/staticfiles/" -STATIC_ROOT = str(ROOT_DIR("staticfiles")) -STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" -WHITENOISE_MANIFEST_STRICT = False - -STATICFILES_DIRS = [str(APPS_DIR.path("static"))] +# https://docs.djangoproject.com/en/dev/ref/settings/#staticfiles-dirs +STATICFILES_DIRS = [str(APPS_DIR / "static")] +# https://docs.djangoproject.com/en/dev/ref/settings/#media-root +MEDIA_ROOT = str(APPS_DIR / "media") +# https://docs.djangoproject.com/en/dev/ref/settings/#media-url MEDIA_URL = "/mediafiles/" -MEDIA_ROOT = str(APPS_DIR("media")) + +# https://docs.djangoproject.com/en/dev/ref/settings/#std-setting-STORAGES +STORAGES = { + "staticfiles": { + "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage", + } +} + +# https://whitenoise.readthedocs.io/en/latest/django.html#WHITENOISE_MANIFEST_STRICT +WHITENOISE_MANIFEST_STRICT = False # TEMPLATES # ------------------------------------------------------------------------------ @@ -194,7 +211,7 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND "BACKEND": "django.template.backends.django.DjangoTemplates", # https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs - "DIRS": [str(APPS_DIR.path("templates"))], + "DIRS": [str(APPS_DIR / "templates")], "OPTIONS": { # https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders # https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types @@ -223,7 +240,7 @@ # FIXTURES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#fixture-dirs -FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),) +FIXTURE_DIRS = (str(APPS_DIR / "fixtures"),) # SECURITY # ------------------------------------------------------------------------------ @@ -231,31 +248,45 @@ SESSION_COOKIE_HTTPONLY = True # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly CSRF_COOKIE_HTTPONLY = True -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-browser-xss-filter -SECURE_BROWSER_XSS_FILTER = True # https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options X_FRAME_OPTIONS = "DENY" +# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins +CSRF_TRUSTED_ORIGINS = env.json("CSRF_TRUSTED_ORIGINS", default=[]) -CSRF_TRUSTED_ORIGINS = json.loads(env("CSRF_TRUSTED_ORIGINS", default="[]")) +# https://github.com/adamchainz/django-cors-headers#cors_allow_all_origins-bool +CORS_ORIGIN_ALLOW_ALL = True # WARNING: This is not secure +# https://github.com/adamchainz/django-cors-headers#cors_allowed_origin_regexes-sequencestr--patternstr +# CORS_URLS_REGEX = r"^/api/.*$" # EMAIL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend EMAIL_BACKEND = env( - "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend" + "DJANGO_EMAIL_BACKEND", + default="django.core.mail.backends.smtp.EmailBackend", ) -# https://docs.djangoproject.com/en/2.2/ref/settings/#email-timeout +# https://docs.djangoproject.com/en/dev/ref/settings/#email-timeout EMAIL_TIMEOUT = 5 +# https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email +DEFAULT_FROM_EMAIL = env( + "EMAIL_FROM", default="Open Healthcare Network " +) +EMAIL_HOST = env("EMAIL_HOST", default="localhost") +EMAIL_PORT = env("EMAIL_PORT", default=587) +EMAIL_HOST_USER = env("EMAIL_USER", default="") +EMAIL_HOST_PASSWORD = env("EMAIL_PASSWORD", default="") +EMAIL_USE_TLS = env("EMAIL_USE_TLS", default=False) # ADMIN # ------------------------------------------------------------------------------ -# Django Admin URL. -ADMIN_URL = "admin/" # https://docs.djangoproject.com/en/dev/ref/settings/#admins -ADMINS = [("""👪""", "admin@coronasafe.in")] +ADMINS = [("""👪""", "admin@ohc.network")] # https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS +# Django Admin URL. +ADMIN_URL = env("DJANGO_ADMIN_URL", default="admin/") + # LOGGING # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#logging @@ -282,7 +313,7 @@ # Django Rest Framework # ------------------------------------------------------------------------------ - +# https://www.django-rest-framework.org/api-guide/settings/ REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( # "rest_framework.authentication.BasicAuthentication", @@ -296,17 +327,22 @@ "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", "PAGE_SIZE": 14, "SEARCH_PARAM": "search_text", + "DEFAULT_SCHEMA_CLASS": "care.utils.schema.AutoSchema", } -# Your stuff... +# drf-spectacular (schema generation) # ------------------------------------------------------------------------------ +# https://drf-spectacular.readthedocs.io/en/latest/settings.html +SPECTACULAR_SETTINGS = { + "TITLE": "Care API", + "DESCRIPTION": "Documentation of API endpoints of Care ", + "VERSION": "1.0.0", + # "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"], +} - -ACCOUNT_EMAIL_VERIFICATION = False -LOGOUT_REDIRECT_URL = "/" -STAFF_ACCOUNT_TYPE = 10 - -# Simple JWT +# Simple JWT (JWT Authentication) +# ------------------------------------------------------------------------------ +# https://django-rest-framework-simplejwt.readthedocs.io/en/latest/settings.html SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta( minutes=env("JWT_ACCESS_TOKEN_LIFETIME", default=10) @@ -318,25 +354,9 @@ "USER_ID_FIELD": "external_id", } - -def GETKEY(group, request): - return "ratelimit" - - -DJANGO_RATE_LIMIT = env("RATE_LIMIT", default="5/10m") - -GOOGLE_RECAPTCHA_SECRET_KEY = env("GOOGLE_RECAPTCHA_SECRET_KEY", default="") - -GOOGLE_RECAPTCHA_SITE_KEY = env("GOOGLE_RECAPTCHA_SITE_KEY", default="") - -GOOGLE_CAPTCHA_POST_KEY = "g-recaptcha-response" - -CORS_ORIGIN_ALLOW_ALL = True - -MAINTENANCE_MODE = int(env("MAINTENANCE_MODE", default="0")) - -# Celery +# Celery (background tasks) # ------------------------------------------------------------------------------ +# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-timezone if USE_TZ: # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-timezone CELERY_TIMEZONE = TIME_ZONE @@ -359,78 +379,39 @@ def GETKEY(group, request): # http://docs.celeryproject.org/en/latest/userguide/configuration.html#beat-scheduler CELERY_TIMEZONE = "Asia/Kolkata" -CSV_REQUEST_PARAMETER = "csv" - -DEFAULT_FROM_EMAIL = env( - "EMAIL_FROM", default="Coronasafe network " -) +# Maintenance Mode +# ------------------------------------------------------------------------------ +# https://github.com/fabiocaccamo/django-maintenance-mode/tree/main#configuration-optional +MAINTENANCE_MODE = int(env("MAINTENANCE_MODE", default="0")) -CURRENT_DOMAIN = env("CURRENT_DOMAIN", default="localhost:8000") +# Password Reset +# ------------------------------------------------------------------------------ +# https://github.com/anexia-it/django-rest-passwordreset#configuration--settings DJANGO_REST_PASSWORDRESET_NO_INFORMATION_LEAKAGE = True - DJANGO_REST_MULTITOKENAUTH_RESET_TOKEN_EXPIRY_TIME = 1 - +# https://github.com/anexia-it/django-rest-passwordreset#custom-email-lookup DJANGO_REST_LOOKUP_FIELD = "username" -CHROME_WINDOW_SIZE = "2480,3508" +# Hardcopy settings (pdf generation) +# ------------------------------------------------------------------------------ +# https://github.com/loftylabs/django-hardcopy#installation +CHROME_WINDOW_SIZE = "2480,3508" CHROME_PATH = "/usr/bin/chromium" -IS_PRODUCTION = False - -OTP_REPEAT_WINDOW = 6 # OTPs will only be valid for 6 hours to login - -OTP_MAX_REPEATS_WINDOW = ( - 10 # can only send this many OTP's in current OTP_REPEAT_WINDOW -) - -OTP_LENGTH = 5 - -# ICD -ICD_SCRAPER_ROOT_CONCEPTS_URL = ( - "https://icd.who.int/browse11/l-m/en/JsonGetRootConcepts" -) -ICD_SCRAPER_CHILD_CONCEPTS_URL = ( - "https://icd.who.int/browse11/l-m/en/JsonGetChildrenConcepts" -) - -# SMS -USE_SMS = False - -DEFAULT_VAPID_PUBLIC_KEY = "BKNxrOpAeB_OBfXI-GlRAlw_vUVCc3mD_AkpE74iZj97twMOHXEFUeJqA7bDqGY10O-RmkvG30NaMf5ZWihnT3k" - -DEFAULT_VAPID_PRIVATE_KEY = "7mf3OFreFsgFF4jd8A71ZGdVaj8kpJdOto4cFbfAS-s" - -VAPID_PUBLIC_KEY = env("VAPID_PUBLIC_KEY", default=DEFAULT_VAPID_PUBLIC_KEY) -VAPID_PRIVATE_KEY = env("VAPID_PRIVATE_KEY", default=DEFAULT_VAPID_PRIVATE_KEY) - -####################### -# File Upload Parameters - -FILE_UPLOAD_BUCKET = env("FILE_UPLOAD_BUCKET", default="") -# FILE_UPLOAD_REGION = env("FILE_UPLOAD_REGION", default="care-patient-staging") -FILE_UPLOAD_KEY = env("FILE_UPLOAD_KEY", default="") -FILE_UPLOAD_SECRET = env("FILE_UPLOAD_SECRET", default="") -FILE_UPLOAD_BUCKET_ENDPOINT = env( - "FILE_UPLOAD_BUCKET_ENDPOINT", - default=f"https://{FILE_UPLOAD_BUCKET}.s3.amazonaws.com", -) - -FACILITY_S3_BUCKET = env("FACILITY_S3_BUCKET", default="") -FACILITY_S3_REGION = env("FACILITY_S3_REGION_CODE", default="ap-south-1") -FACILITY_S3_KEY = env("FACILITY_S3_KEY", default="") -FACILITY_S3_SECRET = env("FACILITY_S3_SECRET", default="") -FACILITY_S3_BUCKET_ENDPOINT = env( - "FACILITY_S3_BUCKET_ENDPOINT", - default=f"https://{FACILITY_S3_BUCKET}.s3.{FACILITY_S3_REGION}.amazonaws.com", -) -FACILITY_S3_STATIC_PREFIX = env( - "FACILITY_S3_STATIC_PREFIX", - default=f"https://{FACILITY_S3_BUCKET}.s3.{FACILITY_S3_REGION}.amazonaws.com", -) +# Health Django (Health Check Config) +# ------------------------------------------------------------------------------ +# https://github.com/vigneshhari/healthy_django +HEALTHY_DJANGO = [ + DjangoDatabaseHealthCheck( + "Database", slug="main_database", connection_name="default" + ), + DjangoCacheHealthCheck("Cache", slug="main_cache", connection_name="default"), +] # Audit logs +# ------------------------------------------------------------------------------ AUDIT_LOG_ENABLED = env.bool("AUDIT_LOG_ENABLED", default=False) AUDIT_LOG = { "globals": { @@ -463,40 +444,48 @@ def GETKEY(group, request): }, } -SEND_SMS_NOTIFICATION = False +# OTP +# ------------------------------------------------------------------------------ +OTP_REPEAT_WINDOW = 6 # OTPs will only be valid for 6 hours to login +OTP_MAX_REPEATS_WINDOW = 10 # times OTPs can be sent within OTP_REPEAT_WINDOW +OTP_LENGTH = 5 -# Whatsapp Integrations -ENABLE_WHATSAPP = env.bool("ENABLE_WHATSAPP", default=False) -WHATSAPP_API_ENDPOINT = env("WHATSAPP_API_ENDPOINT", default="") -WHATSAPP_API_USERNAME = env("WHATSAPP_API_USERNAME", default="") -WHATSAPP_API_PASSWORD = env("WHATSAPP_API_PASSWORD", default="") -WHATSAPP_ENCRYPTION_KEY = env("WHATSAPP_ENCRYPTION_KEY", default="") -WHATSAPP_MESSAGE_CONFIG = env("WHATSAPP_MESSAGE_CONFIG", default=None) +# ICD +# ------------------------------------------------------------------------------ +ICD_SCRAPER_ROOT_CONCEPTS_URL = ( + "https://icd.who.int/browse11/l-m/en/JsonGetRootConcepts" +) +ICD_SCRAPER_CHILD_CONCEPTS_URL = ( + "https://icd.who.int/browse11/l-m/en/JsonGetChildrenConcepts" +) -DISABLE_RATELIMIT = False +# Rate Limiting +# ------------------------------------------------------------------------------ +DISABLE_RATELIMIT = env.bool("DISABLE_RATELIMIT", default=False) +DJANGO_RATE_LIMIT = env("RATE_LIMIT", default="5/10m") +GETKEY = "ratelimit" +GOOGLE_RECAPTCHA_SECRET_KEY = env("GOOGLE_RECAPTCHA_SECRET_KEY", default="") +GOOGLE_RECAPTCHA_SITE_KEY = env("GOOGLE_RECAPTCHA_SITE_KEY", default="") +GOOGLE_CAPTCHA_POST_KEY = "g-recaptcha-response" -ENABLE_ADMIN_REPORTS = env.bool("ENABLE_ADMIN_REPORTS", default=False) +# SMS +# ------------------------------------------------------------------------------ +USE_SMS = False -# Health Check Config +# Push Notifications +# ------------------------------------------------------------------------------ +VAPID_PUBLIC_KEY = env( + "VAPID_PUBLIC_KEY", + default="BKNxrOpAeB_OBfXI-GlRAlw_vUVCc3mD_AkpE74iZj97twMOHXEFUeJqA7bDqGY10O-RmkvG30NaMf5ZWihnT3k", +) +VAPID_PRIVATE_KEY = env( + "VAPID_PRIVATE_KEY", default="7mf3OFreFsgFF4jd8A71ZGdVaj8kpJdOto4cFbfAS-s" +) +SEND_SMS_NOTIFICATION = False -default_configuration = [ - DjangoDatabaseHealthCheck( - "Database", slug="main_database", connection_name="default" - ), - DjangoCacheHealthCheck("Cache", slug="main_cache", connection_name="default"), -] -# DjangoCeleryQueueLengthHealthCheck( -# "Celery Queue Length", -# slug="celery_queue", -# broker=CELERY_BROKER_URL, -# queue_name="celery", -# info_length=10, -# warning_length=20, -# alert_length=30, -# ), - -HEALTHY_DJANGO = default_configuration +# Cloud and Buckets +# ------------------------------------------------------------------------------ CLOUD_PROVIDER = env("CLOUD_PROVIDER", default="aws").upper() CLOUD_REGION = env("CLOUD_REGION", default="ap-south-1") @@ -504,8 +493,51 @@ def GETKEY(group, request): if CLOUD_PROVIDER not in csp_config.CSProvider.__members__: print(f"Warning Invalid CSP Found! {CLOUD_PROVIDER}") +if USE_S3 := env.bool("USE_S3", default=False): + # aws settings + AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID") + AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY") + AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME") + AWS_DEFAULT_ACL = "public-read" + AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com" + AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"} + +FILE_UPLOAD_BUCKET = env("FILE_UPLOAD_BUCKET", default="") +# FILE_UPLOAD_REGION = env("FILE_UPLOAD_REGION", default="care-patient-staging") +FILE_UPLOAD_KEY = env("FILE_UPLOAD_KEY", default="") +FILE_UPLOAD_SECRET = env("FILE_UPLOAD_SECRET", default="") +FILE_UPLOAD_BUCKET_ENDPOINT = env( + "FILE_UPLOAD_BUCKET_ENDPOINT", + default=f"https://{FILE_UPLOAD_BUCKET}.s3.amazonaws.com", +) + +FACILITY_S3_BUCKET = env("FACILITY_S3_BUCKET", default="") +FACILITY_S3_REGION = env("FACILITY_S3_REGION_CODE", default="ap-south-1") +FACILITY_S3_KEY = env("FACILITY_S3_KEY", default="") +FACILITY_S3_SECRET = env("FACILITY_S3_SECRET", default="") +FACILITY_S3_BUCKET_ENDPOINT = env( + "FACILITY_S3_BUCKET_ENDPOINT", + default=f"https://{FACILITY_S3_BUCKET}.s3.{FACILITY_S3_REGION}.amazonaws.com", +) +FACILITY_S3_STATIC_PREFIX = env( + "FACILITY_S3_STATIC_PREFIX", + default=f"https://{FACILITY_S3_BUCKET}.s3.{FACILITY_S3_REGION}.amazonaws.com", +) + + +# for setting the shifting mode +PEACETIME_MODE = env.bool("PEACETIME_MODE", default=True) + +# for exporting csv +CSV_REQUEST_PARAMETER = "csv" + +# current hosted domain +CURRENT_DOMAIN = env("CURRENT_DOMAIN", default="localhost:8000") + +# open id connect JWKS = JsonWebKey.import_key_set( json.loads(base64.b64decode(env("JWKS_BASE64", default=generate_encoded_jwks()))) ) -PEACETIME_MODE = env.bool("PEACETIME_MODE", default=True) +# ?! +IS_PRODUCTION = False diff --git a/config/settings/deployment.py b/config/settings/deployment.py index 91d6a1266c..63e1b2ccdc 100644 --- a/config/settings/deployment.py +++ b/config/settings/deployment.py @@ -11,34 +11,14 @@ # GENERAL # ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env("DJANGO_SECRET_KEY") -# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = json.loads(env("DJANGO_ALLOWED_HOSTS", default='["*"]')) # noqa F405 # DATABASES # ------------------------------------------------------------------------------ -# TODO: rename POSTGIS_URL to DATABASE_URL -DATABASES["default"] = env.db("POSTGIS_URL") # noqa F405 +DATABASES["default"] = env.db("DATABASE_URL", default=env("POSTGIS_URL")) # noqa F405 DATABASES["default"]["ATOMIC_REQUESTS"] = True # noqa F405 DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405 -# CACHES -# ------------------------------------------------------------------------------ -CACHES = { - "default": { - "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": env("REDIS_URL"), - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - # Mimicing memcache behavior. - # http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior - "IGNORE_EXCEPTIONS": True, - }, - } -} - # SECURITY # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header @@ -64,9 +44,6 @@ "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True ) -# MEDIA -# ------------------------------------------------------------------------------ - # TEMPLATES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#templates @@ -82,26 +59,14 @@ # EMAIL # ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email - -EMAIL_HOST = env("EMAIL_HOST") -EMAIL_HOST_USER = env("EMAIL_USER") -EMAIL_HOST_PASSWORD = env("EMAIL_PASSWORD") -EMAIL_PORT = env("EMAIL_PORT", default=587) EMAIL_USE_TLS = True -EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" # https://docs.djangoproject.com/en/dev/ref/settings/#server-email SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) # noqa F405 # https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix EMAIL_SUBJECT_PREFIX = env("DJANGO_EMAIL_SUBJECT_PREFIX", default="[Care]") -# ADMIN -# ------------------------------------------------------------------------------ -# Django Admin URL regex. -ADMIN_URL = env("DJANGO_ADMIN_URL") - # Anymail # ------------------------------------------------------------------------------ # https://anymail.readthedocs.io/en/stable/installation/#installing-anymail @@ -122,7 +87,6 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#logging # See https://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. - LOGGING = { "version": 1, "disable_existing_loggers": True, @@ -158,22 +122,17 @@ # Sentry # ------------------------------------------------------------------------------ - -SENTRY_DSN = env("SENTRY_DSN", default="") - -if SENTRY_DSN: - SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) - - sentry_logging = LoggingIntegration( - level=SENTRY_LOG_LEVEL, - event_level=logging.ERROR, # Capture info and above as breadcrumbs # Send errors as events - ) +# https://docs.sentry.io/platforms/python/guides/django/configuration/ +if SENTRY_DSN := env("SENTRY_DSN", default=""): sentry_sdk.init( dsn=SENTRY_DSN, environment=env("SENTRY_ENVIRONMENT", default="deployment-unknown"), traces_sample_rate=env.float("SENTRY_TRACES_SAMPLE_RATE", default=1.0), integrations=[ - sentry_logging, + LoggingIntegration( + level=env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO), + event_level=logging.ERROR, # Capture info and above as breadcrumbs # Send errors as events + ), DjangoIntegration(), CeleryIntegration(), RedisIntegration(), @@ -181,11 +140,7 @@ ) ignore_logger("django.security.DisallowedHost") -# Your stuff... -# ------------------------------------------------------------------------------ - # SMS API KEYS -USE_SMS = False SNS_ACCESS_KEY = env("SNS_ACCESS_KEY") SNS_SECRET_KEY = env("SNS_SECRET_KEY") SNS_REGION = "ap-south-1" diff --git a/config/settings/local.py b/config/settings/local.py index bfcaf28793..6cd8d12b2d 100644 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -1,42 +1,4 @@ from .base import * # noqa -from .base import env - -# GENERAL -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#debug -DEBUG = env.bool("DJANGO_DEBUG", True) -ALLOWED_HOSTS = ["*"] -# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env( - "DJANGO_SECRET_KEY", - default="eXZQzOzx8gV38rDG0Z0fFZWweUGl3LwMZ9aTKqJiXQTI0nKMh0Z7sbHfqT8KFEnd", -) - -# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hostsRUNSERVER_PLUS_PRINT_SQL_TRUNCATE - -# CACHES -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#caches -CACHES = { - "default": { - "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": env("REDIS_URL", default="redis://localhost/"), - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - # Mimicing memcache behavior. - # http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior - "IGNORE_EXCEPTIONS": True, - }, - } -} - - -# EMAIL -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#email-host -EMAIL_HOST = "localhost" -# https://docs.djangoproject.com/en/dev/ref/settings/#email-port -EMAIL_PORT = 1025 # WhiteNoise # ------------------------------------------------------------------------------ @@ -63,11 +25,6 @@ INSTALLED_APPS += ["django_extensions"] # noqa F405 -# Your stuff... -# ------------------------------------------------------------------------------ - -AUDIT_LOG_ENABLED = True - # Celery # ------------------------------------------------------------------------------ @@ -77,24 +34,9 @@ EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" -# Simple JWT -SIMPLE_JWT = { - "ACCESS_TOKEN_LIFETIME": timedelta( # noqa - minutes=env("JWT_ACCESS_TOKEN_LIFETIME", default=1000000000) - ), - "REFRESH_TOKEN_LIFETIME": timedelta( # noqa - minutes=env("JWT_REFRESH_TOKEN_LIFETIME", default=3000000000) - ), - "ROTATE_REFRESH_TOKENS": True, - "USER_ID_FIELD": "external_id", -} - RUNSERVER_PLUS_PRINT_SQL_TRUNCATE = 100000 -AUDIT_LOG_ENABLED = True - DISABLE_RATELIMIT = True - FILE_UPLOAD_BUCKET_ENDPOINT = "http://localstack:4566" FACILITY_S3_BUCKET_ENDPOINT = "http://localstack:4566" diff --git a/config/settings/test.py b/config/settings/test.py index be4a22d593..dabb77eb1f 100644 --- a/config/settings/test.py +++ b/config/settings/test.py @@ -7,12 +7,6 @@ # GENERAL # ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env( - "DJANGO_SECRET_KEY", - default="GlSRVXhTNJXx3Fnu5HUYlgeoMIXy3rl76CIhfOAEHtXE4jrGAEDbAWyzIpW7SVQn", -) - # https://docs.djangoproject.com/en/dev/ref/settings/#test-runner TEST_RUNNER = "django.test.runner.DiscoverRunner" diff --git a/config/urls.py b/config/urls.py index c9c1f26e5c..cb9d85d5d6 100644 --- a/config/urls.py +++ b/config/urls.py @@ -1,12 +1,13 @@ from django.conf import settings -from django.conf.urls import url from django.conf.urls.static import static from django.contrib import admin from django.urls import include, path from django.views import defaults as default_views -from drf_yasg import openapi -from drf_yasg.views import get_schema_view -from rest_framework import permissions +from drf_spectacular.views import ( + SpectacularAPIView, + SpectacularRedocView, + SpectacularSwaggerView, +) from rest_framework_simplejwt.views import TokenVerifyView from care.facility.api.viewsets.open_id import OpenIdConfigView @@ -27,20 +28,6 @@ from .auth_views import TokenObtainPairView, TokenRefreshView from .views import home_view -schema_view = get_schema_view( - openapi.Info( - title="Care API", - default_version="v1", - description="Api Documentation for Care. ** Please use HTTPS for all API calls ( other than local dev) ", - terms_of_service="https://www.google.com/policies/terms/", - contact=openapi.Contact(email="-"), - license=openapi.License(name="MIT License"), - ), - public=True, - permission_classes=(permissions.AllowAny,), -) - - urlpatterns = [ path("", home_view, name="home"), # Django Admin, use {% url 'admin:index' %} @@ -89,7 +76,7 @@ name="hcx_claim_on_submit", ), # Health check urls - url(r"^watchman/", include("watchman.urls")), + # url(r"^watchman/", include("watchman.urls")), path("middleware/verify", MiddlewareAuthenticationVerifyView.as_view()), path( ".well-known/openid-configuration", @@ -125,22 +112,13 @@ urlpatterns = [path("__debug__/", include(debug_toolbar.urls))] + urlpatterns -if not settings.IS_PRODUCTION: +if settings.DEBUG or not settings.IS_PRODUCTION: urlpatterns += [ - # API Docs - url( - r"^swagger(?P\.json|\.yaml)$", - schema_view.without_ui(cache_timeout=0), - name="schema-json", - ), - url( - r"^swagger/$", - schema_view.with_ui("swagger", cache_timeout=0), - name="schema-swagger-ui", - ), - url( - r"^redoc/$", - schema_view.with_ui("redoc", cache_timeout=0), - name="schema-redoc", + path("api/schema/", SpectacularAPIView.as_view(), name="schema"), + path( + "swagger/", + SpectacularSwaggerView.as_view(url_name="schema"), + name="swagger-ui", ), + path("redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc"), ] diff --git a/config/validators.py b/config/validators.py index b07f95b6a9..fdf70e1628 100644 --- a/config/validators.py +++ b/config/validators.py @@ -2,7 +2,7 @@ from django.core.exceptions import ValidationError from django.core.validators import RegexValidator -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext_lazy as _ class NumberValidator(object): diff --git a/config/websocket.py b/config/websocket.py new file mode 100644 index 0000000000..81adfbc664 --- /dev/null +++ b/config/websocket.py @@ -0,0 +1,13 @@ +async def websocket_application(scope, receive, send): + while True: + event = await receive() + + if event["type"] == "websocket.connect": + await send({"type": "websocket.accept"}) + + if event["type"] == "websocket.disconnect": + break + + if event["type"] == "websocket.receive": + if event["text"] == "ping": + await send({"type": "websocket.send", "text": "pong!"}) diff --git a/config/wsgi.py b/config/wsgi.py index f92a3754ff..835d5c2ece 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -15,15 +15,14 @@ """ import os import sys +from pathlib import Path from django.core.wsgi import get_wsgi_application # This allows easy placement of apps within the interior -# care directory. -app_path = os.path.abspath( - os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) -) -sys.path.append(os.path.join(app_path, "care")) +# {{ cookiecutter.project_slug }} directory. +BASE_DIR = Path(__file__).resolve(strict=True).parent.parent +sys.path.append(str(BASE_DIR / "care")) # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks # if running multiple sites in the same mod_wsgi process. To fix this, use # mod_wsgi daemon mode with each site in its own daemon process, or use diff --git a/data/dummy/facility.json b/data/dummy/facility.json index 81817caab8..4900a68c7a 100644 --- a/data/dummy/facility.json +++ b/data/dummy/facility.json @@ -684,7 +684,6 @@ "review_time": null, "created_by": 2, "is_active": true, - "patient_search_id": 1, "date_of_receipt_of_information": "2022-09-27T07:19:20.374Z", "test_id": "", "date_of_test": null, diff --git a/pyproject.toml b/pyproject.toml index 4078b64b0a..80d3b355d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ known_third_party = [ "django_rest_passwordreset", "djangoql", "djqscsv", - "drf_yasg", + "drf_spectacular", "dry_rest_permissions", "environ", "freezegun", diff --git a/requirements/base.txt b/requirements/base.txt index 7a260b1abf..7723cc74be 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,62 +1,58 @@ -pytz==2019.3 # https://github.com/stub42/pytz -python-slugify==4.0.0 # https://github.com/un33k/python-slugify -Pillow==8.0.0 # https://github.com/python-pillow/Pillow -argon2-cffi==19.2.0 # https://github.com/hynek/argon2_cffi -whitenoise==6.0.0 # https://github.com/evansd/whitenoise -redis==3.4.1 # https://github.com/andymccurdy/redis-py +argon2-cffi==21.3.0 # https://github.com/hynek/argon2-cffi/blob/main/CHANGELOG.md +Authlib==1.2.0 # https://docs.authlib.org/en/latest/changelog.html boto3==1.12.23 # For AWS interactions -pycryptodome==3.16.0 -pycryptodomex==3.16.0 +Pillow==9.5.0 # https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst +python-slugify==8.0.1 # https://github.com/un33k/python-slugify/blob/master/CHANGELOG.md +PyJWT==2.7.0 # https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst +redis[hiredis]==4.5.5 # https://github.com/redis/redis-py/blob/master/CHANGES +requests==2.31.0 # https://requests.readthedocs.io/en/latest/community/updates/ +whitenoise==6.4.0 # https://whitenoise.readthedocs.io/en/stable/changelog.html + # Django # ------------------------------------------------------------------------------ -django==2.2.11 # pyup: < 3.0 # https://www.djangoproject.com/ -django-environ==0.4.5 # https://github.com/joke2k/django-environ -django-model-utils==4.0.0 # https://github.com/jazzband/django-model-utils -django-redis==4.11.0 # https://github.com/niwinz/django-redis -django-storages==1.9.1 # For Storing Static Files in AWS -djangorestframework==3.11.0 # https://github.com/encode/django-rest-framework -djangorestframework-simplejwt==4.5.0 # https://github.com/SimpleJWT/django-rest-framework-simplejwt -drf-yasg==1.17.1 # For Api Docs -django-filter==2.4.0 -drf-nested-routers==0.91 -django-multiselectfield==0.1.12 # https://github.com/goinnn/django-multiselectfield -django-simple-history==2.8.0 # https://django-simple-history.readthedocs.io/en/latest/quick_start.html -django-ratelimit==2.0.0 # Limiting Requests -dry-rest-permissions==0.1.10 # For permissions handling -django-cors-headers==3.2.1 -django-watchman==1.1.0 # For Status Endpoints -django-maintenance-mode==0.14.0 # Maintenance mode +django==4.2.2 # https://docs.djangoproject.com/en/dev/releases/ +django-environ==0.10.0 # https://github.com/joke2k/django-environ/blob/main/CHANGELOG.rst +django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils/blob/master/CHANGES.rst +djangorestframework==3.14.0 # https://www.django-rest-framework.org/community/release-notes/ +djangorestframework-simplejwt==5.2.2 # https://github.com/jazzband/djangorestframework-simplejwt/blob/master/CHANGELOG.md +drf-spectacular==0.26.2 # https://drf-spectacular.readthedocs.io/en/latest/changelog.html +django-filter==23.2 # https://github.com/carltongibson/django-filter/blob/main/CHANGES.rst +drf-nested-routers==0.93.3 +django-multiselectfield==0.1.12 # https://github.com/goinnn/django-multiselectfield/blob/master/CHANGES.rst +django-simple-history==3.3.0 # https://github.com/jazzband/django-simple-history/blob/master/CHANGES.rst +django-ratelimit==4.0.0 # https://github.com/jsocol/pystatsd/blob/main/CHANGELOG.md +django-cors-headers==4.0.0 # https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst +django-maintenance-mode==0.18.0 # https://github.com/fabiocaccamo/django-maintenance-mode/blob/main/CHANGELOG.md django-queryset-csv==1.1.0 -django-rest-passwordreset==1.1.0 +django-rest-passwordreset==1.3.0 # https://github.com/anexia-it/django-rest-passwordreset/blob/master/CHANGELOG.md +djangoql==0.17.1 # https://github.com/ivelum/djangoql/blob/master/CHANGES.rst healthy-django>=0.1.0 -# Testing + +django-redis==5.2.0 # https://github.com/jazzband/django-redis/blob/master/CHANGELOG.rst +django-hardcopy==0.1.4 +dry-rest-permissions==0.1.10 # For permissions handling +django-storages==1.9.1 # For Storing Static Files in AWS + +# Json Schema # ------------------------------------------------------------------------------ -mypy==0.910 # https://github.com/python/mypy -django-stubs==1.9.0 # https://github.com/typeddjango/django-stubs -# Experimental +jsonschema==3.2.0 +typed-ast==1.5.0 +# In Memory Database # ------------------------------------------------------------------------------ -djangoql==0.13.1 -# NewRelic for APM -newrelic +littletable==2.0.7 + # Asyncronous Part # ------------------------------------------------------------------------------ celery==4.4.2 -# PDF Printing Tools -# ------------------------------------------------------------------------------ -django-hardcopy==0.1.4 + # WebPushes # ------------------------------------------------------------------------------ pywebpush==1.11.0 -## Override Requirements -Authlib==1.0.1 -PyJWT==v1.7.1 -# Json Schema -jsonschema==3.2.0 -typed-ast==1.5.0 -# In Memory Database -# ------------------------------------------------------------------------------ -littletable==2.0.7 + + # HCX +# ------------------------------------------------------------------------------ fhir.resources==6.5.0 -jwcrypto==1.4.2 -requests==2.31.0 +jwcrypto==1.5.0 # https://github.com/latchset/jwcrypto/releases +pycryptodome==3.16.0 +pycryptodomex==3.16.0 diff --git a/requirements/local.txt b/requirements/local.txt index 74774794d8..4f17a3e96c 100644 --- a/requirements/local.txt +++ b/requirements/local.txt @@ -1,19 +1,20 @@ -r ./base.txt -r ./docs.txt -Werkzeug==1.0.0 # https://github.com/pallets/werkzeug -ipdb==0.13.2 # https://github.com/gotcha/ipdb -psycopg2-binary==2.8.4 # https://github.com/psycopg/psycopg2 -# Code quality -# ------------------------------------------------------------------------------ -isort==5.11.5 # https://github.com/PyCQA/isort -flake8==4.0.1 # https://github.com/PyCQA/flake8 -flake8-isort==4.1.1 # https://github.com/gforcada/flake8-isort -black==22.3.0 # https://github.com/ambv/black -pre-commit==2.19.0 # https://github.com/pre-commit/pre-commit +Werkzeug==2.3.6 # https://werkzeug.palletsprojects.com/en/latest/changes/ +psycopg==3.1.9 # https://psycopg.org/psycopg3/docs/news.html + # Django # ------------------------------------------------------------------------------ -django-debug-toolbar==2.2 # https://github.com/jazzband/django-debug-toolbar -django-extensions==2.2.8 # https://github.com/django-extensions/django-extensions +django-debug-toolbar==4.1 # https://github.com/jazzband/django-debug-toolbar/releases +django-extensions==3.2.3 # https://github.com/django-extensions/django-extensions/blob/main/CHANGELOG.md + +# Code quality +# ------------------------------------------------------------------------------ +isort==5.12.0 # https://github.com/PyCQA/isort/blob/main/CHANGELOG.md +flake8==6.0.0 # https://flake8.pycqa.org/en/latest/release-notes/index.html +black==23.3.0 # https://github.com/psf/black/blob/main/CHANGES.md +pre-commit==3.3.2 # https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md + # Test # ------------------------------- factory-boy==2.12.0 # https://github.com/FactoryBoy/factory_boy @@ -21,8 +22,10 @@ freezegun==0.3.15 # https://github.com/spulec/freezegun coverage[toml]==6.4.1 # https://github.com/nedbat/coveragepy django-coverage-plugin==2.0.3 tblib==1.7.0 # https://github.com/ionelmc/python-tblib -# WatchDog -# ------------------------------- -watchdog==0.10.2 -argh==0.26.2 -debugpy==1.6.3 +mypy==1.3.0 # https://github.com/python/mypy +django-stubs==4.2.1 # https://github.com/typeddjango/django-stubs +djangorestframework-stubs==3.14.1 # https://github.com/typeddjango/djangorestframework-stubs + +# Container development +# ------------------------------------------------------------------------------ +debugpy==1.6.7 diff --git a/requirements/production.txt b/requirements/production.txt index 5cefeb28e5..7ff1e2904d 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -1,10 +1,9 @@ -# PRECAUTION: avoid production dependencies that aren't in development - -r ./base.txt -gunicorn==20.0.4 # https://github.com/benoitc/gunicorn -psycopg2==2.8.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 -sentry-sdk==1.5.12 # https://github.com/getsentry/sentry-python +gunicorn==20.1.0 # https://github.com/benoitc/gunicorn +psycopg==3.1.9 # https://github.com/psycopg/psycopg2 +sentry-sdk # https://github.com/getsentry/sentry-python +newrelic # Django # ------------------------------------------------------------------------------ From 26f34dd09434cb0b9fa0d7ffb155ea218f2c09b7 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Wed, 14 Jun 2023 16:32:35 +0530 Subject: [PATCH 10/24] use default cache backend for django rate limit in tests --- config/settings/test.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/config/settings/test.py b/config/settings/test.py index dabb77eb1f..812743f04e 100644 --- a/config/settings/test.py +++ b/config/settings/test.py @@ -10,16 +10,6 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#test-runner TEST_RUNNER = "django.test.runner.DiscoverRunner" -# CACHES -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#caches -CACHES = { - "default": { - "BACKEND": "django.core.cache.backends.locmem.LocMemCache", - "LOCATION": "", - } -} - # PASSWORDS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#password-hashers From 5f9e9660b277c5d6a744d718f128e2aa46b62837 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 13:05:56 +0530 Subject: [PATCH 11/24] upgrade celery --- care/facility/api/serializers/summary.py | 24 +++ .../api/viewsets/patient_consultation.py | 2 +- care/facility/api/viewsets/summary.py | 175 ++++++++++++++++++ .../facility/management/commands/summarize.py | 16 +- care/facility/tasks/__init__.py | 45 +++++ ...lete_older_notifications.py => cleanup.py} | 7 +- care/facility/tasks/discharge_report.py | 84 +++++++++ care/facility/tasks/notification/generator.py | 67 ------- care/facility/tasks/patient/__init__.py | 0 care/facility/tasks/summarisation.py | 41 ++++ care/facility/{tasks => utils}/icd/scraper.py | 0 .../reports}/discharge_report.py | 73 -------- .../summarisation/district/patient_summary.py | 66 +------ .../summarisation/facility_capacity.py | 82 +------- .../summarisation/patient_summary.py | 51 +---- .../summarisation/tests_summary.py | 60 +----- .../summarisation/triage_summary.py | 46 +---- care/hcx/api/viewsets/gateway.py | 4 +- care/utils/notification_handler.py | 6 +- config/api_router.py | 10 +- config/settings/base.py | 20 +- config/settings/local.py | 2 +- requirements/base.txt | 2 +- 23 files changed, 416 insertions(+), 467 deletions(-) create mode 100644 care/facility/api/serializers/summary.py create mode 100644 care/facility/api/viewsets/summary.py rename care/facility/tasks/{notification/delete_older_notifications.py => cleanup.py} (62%) create mode 100644 care/facility/tasks/discharge_report.py delete mode 100644 care/facility/tasks/notification/generator.py delete mode 100644 care/facility/tasks/patient/__init__.py create mode 100644 care/facility/tasks/summarisation.py rename care/facility/{tasks => utils}/icd/scraper.py (100%) rename care/facility/{tasks/patient => utils/reports}/discharge_report.py (64%) rename care/facility/{ => utils}/summarisation/district/patient_summary.py (61%) rename care/facility/{ => utils}/summarisation/facility_capacity.py (67%) rename care/facility/{ => utils}/summarisation/patient_summary.py (67%) rename care/facility/{ => utils}/summarisation/tests_summary.py (52%) rename care/facility/{ => utils}/summarisation/triage_summary.py (67%) diff --git a/care/facility/api/serializers/summary.py b/care/facility/api/serializers/summary.py new file mode 100644 index 0000000000..0a4f367402 --- /dev/null +++ b/care/facility/api/serializers/summary.py @@ -0,0 +1,24 @@ +from rest_framework import serializers + +from care.facility.api.serializers.facility import FacilitySerializer +from care.facility.models import DistrictScopedSummary, FacilityRelatedSummary + + +class FacilitySummarySerializer(serializers.ModelSerializer): + facility = FacilitySerializer() + + class Meta: + model = FacilityRelatedSummary + exclude = ( + "id", + "s_type", + ) + + +class DistrictSummarySerializer(serializers.ModelSerializer): + class Meta: + model = DistrictScopedSummary + exclude = ( + "id", + "s_type", + ) diff --git a/care/facility/api/viewsets/patient_consultation.py b/care/facility/api/viewsets/patient_consultation.py index 8f5d96dc16..c63cc7b02c 100644 --- a/care/facility/api/viewsets/patient_consultation.py +++ b/care/facility/api/viewsets/patient_consultation.py @@ -20,7 +20,7 @@ from care.facility.models.file_upload import FileUpload from care.facility.models.mixins.permissions.asset import IsAssetUser from care.facility.models.patient_consultation import PatientConsultation -from care.facility.tasks.patient.discharge_report import ( +from care.facility.tasks.discharge_report import ( email_discharge_summary, generate_and_upload_discharge_summary_task, ) diff --git a/care/facility/api/viewsets/summary.py b/care/facility/api/viewsets/summary.py new file mode 100644 index 0000000000..11b7976fa9 --- /dev/null +++ b/care/facility/api/viewsets/summary.py @@ -0,0 +1,175 @@ +from django.utils.decorators import method_decorator +from django.views.decorators.cache import cache_page +from django_filters import rest_framework as filters +from rest_framework.mixins import ListModelMixin +from rest_framework.permissions import IsAuthenticatedOrReadOnly +from rest_framework.viewsets import GenericViewSet + +from care.facility.api.serializers.summary import ( + DistrictSummarySerializer, + FacilitySummarySerializer, +) +from care.facility.models import DistrictScopedSummary, FacilityRelatedSummary + + +class FacilitySummaryFilter(filters.FilterSet): + start_date = filters.DateFilter(field_name="created_date", lookup_expr="gte") + end_date = filters.DateFilter(field_name="created_date", lookup_expr="lte") + facility = filters.UUIDFilter(field_name="facility__external_id") + district = filters.NumberFilter(field_name="facility__district__id") + local_body = filters.NumberFilter(field_name="facility__local_body__id") + state = filters.NumberFilter(field_name="facility__state__id") + + +class FacilityCapacitySummaryViewSet( + ListModelMixin, + GenericViewSet, +): + lookup_field = "external_id" + queryset = ( + FacilityRelatedSummary.objects.filter(s_type="FacilityCapacity") + .order_by("-created_date") + .select_related( + "facility", + "facility__state", + "facility__district", + "facility__local_body", + ) + ) + permission_classes = (IsAuthenticatedOrReadOnly,) + serializer_class = FacilitySummarySerializer + + filter_backends = (filters.DjangoFilterBackend,) + filterset_class = FacilitySummaryFilter + + @method_decorator(cache_page(60 * 10)) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + # def get_queryset(self): + # user = self.request.user + # queryset = self.queryset + # if user.is_superuser: + # return queryset + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: + # return queryset.filter(facility__district=user.district) + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: + # return queryset.filter(facility__state=user.state) + # return queryset.filter(facility__users__id__exact=user.id) + + +class TriageSummaryViewSet(ListModelMixin, GenericViewSet): + lookup_field = "external_id" + queryset = FacilityRelatedSummary.objects.filter(s_type="TriageSummary").order_by( + "-created_date" + ) + permission_classes = (IsAuthenticatedOrReadOnly,) + serializer_class = FacilitySummarySerializer + + filter_backends = (filters.DjangoFilterBackend,) + filterset_class = FacilitySummaryFilter + + # def get_queryset(self): + # user = self.request.user + # queryset = self.queryset + # if user.is_superuser: + # return queryset + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: + # return queryset.filter(facility__district=user.district) + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: + # return queryset.filter(facility__state=user.state) + # return queryset.filter(facility__users__id__exact=user.id) + + @method_decorator(cache_page(60 * 60 * 1)) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + +class TestsSummaryViewSet(ListModelMixin, GenericViewSet): + lookup_field = "external_id" + queryset = FacilityRelatedSummary.objects.filter(s_type="TestSummary").order_by( + "-created_date" + ) + permission_classes = (IsAuthenticatedOrReadOnly,) + serializer_class = FacilitySummarySerializer + + filter_backends = (filters.DjangoFilterBackend,) + filterset_class = FacilitySummaryFilter + + # def get_queryset(self): + # user = self.request.user + # queryset = self.queryset + # if user.is_superuser: + # return queryset + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: + # return queryset.filter(facility__district=user.district) + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: + # return queryset.filter(facility__state=user.state) + # return queryset.filter(facility__users__id__exact=user.id) + + @method_decorator(cache_page(60 * 60 * 10)) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + +class PatientSummaryViewSet(ListModelMixin, GenericViewSet): + lookup_field = "external_id" + queryset = FacilityRelatedSummary.objects.filter(s_type="PatientSummary").order_by( + "-created_date" + ) + permission_classes = (IsAuthenticatedOrReadOnly,) + serializer_class = FacilitySummarySerializer + + filter_backends = (filters.DjangoFilterBackend,) + filterset_class = FacilitySummaryFilter + + @method_decorator(cache_page(60 * 10)) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + # def get_queryset(self): + # user = self.request.user + # queryset = self.queryset + # if user.is_superuser: + # return queryset + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: + # return queryset.filter(facility__district=user.district) + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: + # return queryset.filter(facility__state=user.state) + # return queryset.filter(facility__users__id__exact=user.id) + + +class DistrictSummaryFilter(filters.FilterSet): + start_date = filters.DateFilter(field_name="created_date", lookup_expr="gte") + end_date = filters.DateFilter(field_name="created_date", lookup_expr="lte") + district = filters.NumberFilter(field_name="district__id") + state = filters.NumberFilter(field_name="district__state__id") + + +class DistrictPatientSummaryViewSet(ListModelMixin, GenericViewSet): + lookup_field = "external_id" + queryset = ( + DistrictScopedSummary.objects.filter(s_type="PatientSummary") + .order_by("-created_date") + .select_related("district", "district__state") + ) + permission_classes = (IsAuthenticatedOrReadOnly,) + serializer_class = DistrictSummarySerializer + + filter_backends = (filters.DjangoFilterBackend,) + filterset_class = DistrictSummaryFilter + + @method_decorator(cache_page(60 * 10)) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + # def get_queryset(self): + # user = self.request.user + # queryset = self.queryset + # if user.is_superuser: + # return queryset + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: + # return queryset.filter(facility__district=user.district) + # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: + # return queryset.filter(facility__state=user.state) + # return queryset.filter(facility__users__id__exact=user.id) diff --git a/care/facility/management/commands/summarize.py b/care/facility/management/commands/summarize.py index 34ea098f99..bc77fd5d03 100644 --- a/care/facility/management/commands/summarize.py +++ b/care/facility/management/commands/summarize.py @@ -1,8 +1,12 @@ from django.core.management.base import BaseCommand -from care.facility.summarisation.district.patient_summary import DistrictPatientSummary -from care.facility.summarisation.facility_capacity import FacilityCapacitySummary -from care.facility.summarisation.patient_summary import PatientSummary +from care.facility.utils.summarisation.district.patient_summary import ( + district_patient_summary, +) +from care.facility.utils.summarisation.facility_capacity import ( + facility_capacity_summary, +) +from care.facility.utils.summarisation.patient_summary import patient_summary class Command(BaseCommand): @@ -13,9 +17,9 @@ class Command(BaseCommand): help = "Force Create Summary Objects" def handle(self, *args, **options): - PatientSummary() + patient_summary() print("Patients Summarised") - FacilityCapacitySummary() + facility_capacity_summary() print("Capacity Summarised") - DistrictPatientSummary() + district_patient_summary() print("District Wise Patient Summarised") diff --git a/care/facility/tasks/__init__.py b/care/facility/tasks/__init__.py index e69de29bb2..7ebf63cdaa 100644 --- a/care/facility/tasks/__init__.py +++ b/care/facility/tasks/__init__.py @@ -0,0 +1,45 @@ +from celery import current_app +from celery.schedules import crontab + +from care.facility.tasks.cleanup import delete_old_notifications +from care.facility.tasks.summarisation import ( + summarise_district_patient, + summarise_facility_capacity, + summarise_patient, + summarise_tests, + summarise_triage, +) + + +@current_app.on_after_finalize.connect +def setup_periodic_tasks(sender, **kwargs): + sender.add_periodic_task( + crontab(minute="0", hour="0"), + delete_old_notifications.s(), + name="delete_old_notifications", + ) + sender.add_periodic_task( + crontab(hour="*/4", minute=59), + summarise_triage.s(), + name="summarise_triage", + ) + sender.add_periodic_task( + crontab(hour=23, minute=59), + summarise_tests.s(), + name="summarise_tests", + ) + sender.add_periodic_task( + crontab(minute="*/5"), + summarise_facility_capacity.s(), + name="summarise_facility_capacity", + ) + sender.add_periodic_task( + crontab(hour="*/1", minute=59), + summarise_patient.s(), + name="summarise_patient", + ) + sender.add_periodic_task( + crontab(hour="*/1", minute=59), + summarise_district_patient.s(), + name="summarise_district_patient", + ) diff --git a/care/facility/tasks/notification/delete_older_notifications.py b/care/facility/tasks/cleanup.py similarity index 62% rename from care/facility/tasks/notification/delete_older_notifications.py rename to care/facility/tasks/cleanup.py index d537e555f2..3f913142cc 100644 --- a/care/facility/tasks/notification/delete_older_notifications.py +++ b/care/facility/tasks/cleanup.py @@ -1,15 +1,12 @@ from datetime import timedelta -from celery.decorators import periodic_task -from celery.schedules import crontab +from celery import shared_task from django.utils import timezone from care.facility.models.notification import Notification -@periodic_task( - run_every=crontab(minute="0", hour="0") -) # Run the task daily at midnight +@shared_task def delete_old_notifications(): ninety_days_ago = timezone.now() - timedelta(days=90) Notification.objects.filter(created_date__lte=ninety_days_ago).delete() diff --git a/care/facility/tasks/discharge_report.py b/care/facility/tasks/discharge_report.py new file mode 100644 index 0000000000..13c980caa6 --- /dev/null +++ b/care/facility/tasks/discharge_report.py @@ -0,0 +1,84 @@ +import tempfile +from uuid import uuid4 + +import boto3 +from celery import shared_task +from django.conf import settings +from django.core.mail import EmailMessage + +from care.facility.models import PatientConsultation +from care.facility.models.file_upload import FileUpload +from care.facility.utils.reports.discharge_report import ( + generate_and_upload_discharge_summary, + generate_discharge_summary_pdf, + get_discharge_summary_data, +) +from care.utils.csp import config as cs_provider + + +@shared_task +def generate_and_upload_discharge_summary_task(consultation_id): + file_db_entry = generate_and_upload_discharge_summary(consultation_id) + return file_db_entry.id + + +@shared_task +def email_discharge_summary(consultation_id, email): + generate_and_upload_discharge_summary_task(consultation_id) + + summary = ( + FileUpload.objects.filter( + file_type=FileUpload.FileType.DISCHARGE_SUMMARY.value, + associating_id=consultation_id, + ) + .order_by("-created_date") + .first() + ) + + msg = EmailMessage( + "Patient Discharge Summary", + "Please find the attached file", + settings.DEFAULT_FROM_EMAIL, + (email,), + ) + msg.content_subtype = "html" + msg.attach(summary.name, summary.get_content(), "application/pdf") + msg.send() + + return True + + +@shared_task +def generate_discharge_report_signed_url(patient_external_id): + consultation = ( + PatientConsultation.objects.filter(patient__external_id=patient_external_id) + .order_by("-created_date") + .first() + ) + if not consultation: + return None + + data = get_discharge_summary_data(consultation) + + signed_url = None + with tempfile.NamedTemporaryFile(suffix=".pdf") as file: + generate_discharge_summary_pdf(data, file) + s3 = boto3.client( + "s3", + **cs_provider.get_client_config(), + ) + image_location = f"discharge_summary/{uuid4()}.pdf" + s3.put_object( + Bucket=settings.FILE_UPLOAD_BUCKET, + Key=image_location, + Body=file, + ) + signed_url = s3.generate_presigned_url( + "get_object", + Params={ + "Bucket": settings.FILE_UPLOAD_BUCKET, + "Key": image_location, + }, + ExpiresIn=2 * 24 * 60 * 60, # seconds + ) + return signed_url diff --git a/care/facility/tasks/notification/generator.py b/care/facility/tasks/notification/generator.py deleted file mode 100644 index 03c6aa1d03..0000000000 --- a/care/facility/tasks/notification/generator.py +++ /dev/null @@ -1,67 +0,0 @@ -# import celery -# from django.conf import settings -# from pywebpush import WebPushException, webpush - -# from care.facility.models.facility import FacilityUser -# from care.facility.models.notification import Notification -# from care.facility.models.patient import PatientRegistration -# from care.users.models import User -# from care.utils.sms.sendSMS import sendSMS - - -# def generate_sms_for_user(phone_numbers, message): -# sendSMS(phone_numbers, message, many=True) - - -# @celery.task() -# def generate_notifications_for_facility(facility_id, data, defer_notifications): -# extra_users = data.get("extra_users", []) -# del data["extra_users"] -# caused_user_id = data.get("caused_by_id", None) -# caused_user = None -# if caused_user_id: -# caused_user = User.objects.get(id=caused_user_id) -# facility_users = FacilityUser.objects.filter(facility_id=facility_id) -# # notifications = [] -# for facility_user in facility_users: -# if facility_user.user.id != caused_user.id: -# generate_message_for_user(facility_user.user, data.copy()) -# if not defer_notifications: -# send_webpush_user(facility_user.user, data["message"]) -# for user_id in extra_users: -# user_obj = User.objects.get(id=user_id) -# if user_obj.id != caused_user.id: -# generate_message_for_user(user_obj, data.copy()) -# if not defer_notifications: -# send_webpush_user(user_obj, data["message"]) -# # Notification.objects.bulk_create(notifications) -# # for facility_user in facility_users: -# # if not defer_notifications: -# # pass -# # # Delay task to send notifications - - -# def send_webpush_user(user, message): -# try: -# if user.pf_endpoint and user.pf_p256dh and user.pf_auth: -# webpush( -# subscription_info={ -# "endpoint": user.pf_endpoint, -# "keys": {"p256dh": user.pf_p256dh, "auth": user.pf_auth}, -# }, -# data=message, -# vapid_private_key=settings.VAPID_PRIVATE_KEY, -# vapid_claims={"sub": "mailto:info@coronasafe.network",}, -# ) -# except WebPushException as ex: -# print("Web Push Failed with Exception: {}", repr(ex)) -# if ex.response and ex.response.json(): -# extra = ex.response.json() -# print( -# "Remote service replied with a {}:{}, {}", extra.code, extra.errno, extra.message, -# ) - - -# def generate_message_for_user(user, data): -# data["intended_for_id"] = user.id -# return Notification(**data).save() diff --git a/care/facility/tasks/patient/__init__.py b/care/facility/tasks/patient/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/care/facility/tasks/summarisation.py b/care/facility/tasks/summarisation.py new file mode 100644 index 0000000000..774829df7c --- /dev/null +++ b/care/facility/tasks/summarisation.py @@ -0,0 +1,41 @@ +from celery import shared_task + +from care.facility.utils.summarisation.district.patient_summary import ( + district_patient_summary, +) +from care.facility.utils.summarisation.facility_capacity import ( + facility_capacity_summary, +) +from care.facility.utils.summarisation.patient_summary import patient_summary +from care.facility.utils.summarisation.tests_summary import tests_summary +from care.facility.utils.summarisation.triage_summary import triage_summary + + +@shared_task +def summarise_triage(): + triage_summary() + print("Summarised Triages") + + +@shared_task +def summarise_tests(): + tests_summary() + print("Summarised Tests") + + +@shared_task +def summarise_facility_capacity(): + facility_capacity_summary() + print("Summarised Facility Capacities") + + +@shared_task +def summarise_patient(): + patient_summary() + print("Summarised Patients") + + +@shared_task +def summarise_district_patient(): + district_patient_summary() + print("Summarised District Patients") diff --git a/care/facility/tasks/icd/scraper.py b/care/facility/utils/icd/scraper.py similarity index 100% rename from care/facility/tasks/icd/scraper.py rename to care/facility/utils/icd/scraper.py diff --git a/care/facility/tasks/patient/discharge_report.py b/care/facility/utils/reports/discharge_report.py similarity index 64% rename from care/facility/tasks/patient/discharge_report.py rename to care/facility/utils/reports/discharge_report.py index bd75e4937a..ffc3325889 100644 --- a/care/facility/tasks/patient/discharge_report.py +++ b/care/facility/utils/reports/discharge_report.py @@ -1,10 +1,6 @@ import tempfile from uuid import uuid4 -import boto3 -import celery -from django.conf import settings -from django.core.mail import EmailMessage from django.db.models import Q from django.template.loader import render_to_string from django.utils import timezone @@ -22,7 +18,6 @@ from care.facility.models.file_upload import FileUpload from care.facility.static_data.icd11 import get_icd11_diagnoses_objects_by_ids from care.hcx.models.policy import Policy -from care.utils.csp import config as cs_provider def get_discharge_summary_data(consultation: PatientConsultation): @@ -114,71 +109,3 @@ def generate_and_upload_discharge_summary(consultation_id): file_db_entry.save() return file_db_entry - - -@celery.task() -def generate_and_upload_discharge_summary_task(consultation_id): - file_db_entry = generate_and_upload_discharge_summary(consultation_id) - return file_db_entry.id - - -@celery.task() -def email_discharge_summary(consultation_id, email): - generate_and_upload_discharge_summary_task(consultation_id) - - summary = ( - FileUpload.objects.filter( - file_type=FileUpload.FileType.DISCHARGE_SUMMARY.value, - associating_id=consultation_id, - ) - .order_by("-created_date") - .first() - ) - - msg = EmailMessage( - "Patient Discharge Summary", - "Please find the attached file", - settings.DEFAULT_FROM_EMAIL, - (email,), - ) - msg.content_subtype = "html" - msg.attach(summary.name, summary.get_content(), "application/pdf") - msg.send() - - return True - - -@celery.task() -def generate_discharge_report_signed_url(patient_external_id): - consultation = ( - PatientConsultation.objects.filter(patient__external_id=patient_external_id) - .order_by("-created_date") - .first() - ) - if not consultation: - return None - - data = get_discharge_summary_data(consultation) - - signed_url = None - with tempfile.NamedTemporaryFile(suffix=".pdf") as file: - generate_discharge_summary_pdf(data, file) - s3 = boto3.client( - "s3", - **cs_provider.get_client_config(), - ) - image_location = f"discharge_summary/{uuid4()}.pdf" - s3.put_object( - Bucket=settings.FILE_UPLOAD_BUCKET, - Key=image_location, - Body=file, - ) - signed_url = s3.generate_presigned_url( - "get_object", - Params={ - "Bucket": settings.FILE_UPLOAD_BUCKET, - "Key": image_location, - }, - ExpiresIn=2 * 24 * 60 * 60, # seconds - ) - return signed_url diff --git a/care/facility/summarisation/district/patient_summary.py b/care/facility/utils/summarisation/district/patient_summary.py similarity index 61% rename from care/facility/summarisation/district/patient_summary.py rename to care/facility/utils/summarisation/district/patient_summary.py index 201e5eb3e4..31997109fb 100644 --- a/care/facility/summarisation/district/patient_summary.py +++ b/care/facility/utils/summarisation/district/patient_summary.py @@ -1,66 +1,12 @@ -from celery.decorators import periodic_task -from celery.schedules import crontab from django.db.models import Q -from django.utils.decorators import method_decorator from django.utils.timezone import now -from django.views.decorators.cache import cache_page -from django_filters import rest_framework as filters -from rest_framework import serializers -from rest_framework.mixins import ListModelMixin -from rest_framework.permissions import IsAuthenticatedOrReadOnly -from rest_framework.viewsets import GenericViewSet from care.facility.models import DistrictScopedSummary, PatientRegistration from care.facility.models.patient_base import BedTypeChoices from care.users.models import District, LocalBody -class DistrictSummarySerializer(serializers.ModelSerializer): - class Meta: - model = DistrictScopedSummary - exclude = ( - "id", - "s_type", - ) - - -class DistrictSummaryFilter(filters.FilterSet): - start_date = filters.DateFilter(field_name="created_date", lookup_expr="gte") - end_date = filters.DateFilter(field_name="created_date", lookup_expr="lte") - district = filters.NumberFilter(field_name="district__id") - state = filters.NumberFilter(field_name="district__state__id") - - -class DistrictPatientSummaryViewSet(ListModelMixin, GenericViewSet): - lookup_field = "external_id" - queryset = ( - DistrictScopedSummary.objects.filter(s_type="PatientSummary") - .order_by("-created_date") - .select_related("district", "district__state") - ) - permission_classes = (IsAuthenticatedOrReadOnly,) - serializer_class = DistrictSummarySerializer - - filter_backends = (filters.DjangoFilterBackend,) - filterset_class = DistrictSummaryFilter - - @method_decorator(cache_page(60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - - # def get_queryset(self): - # user = self.request.user - # queryset = self.queryset - # if user.is_superuser: - # return queryset - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: - # return queryset.filter(facility__district=user.district) - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: - # return queryset.filter(facility__state=user.state) - # return queryset.filter(facility__users__id__exact=user.id) - - -def DistrictPatientSummary(): +def district_patient_summary(): for district_object in District.objects.all(): district_summary = { "name": district_object.name, @@ -149,18 +95,10 @@ def DistrictPatientSummary(): district_summary_old.save() else: modified_date = now() - district_summary.update( - {"modified_date": modified_date.strftime("%d-%m-%Y %H:%M")} - ) + district_summary["modified_date"] = modified_date.strftime("%d-%m-%Y %H:%M") DistrictScopedSummary( s_type="PatientSummary", district_id=district_object.id, data=district_summary, ).save() return True - - -@periodic_task(run_every=crontab(hour="*/1", minute=59)) -def run_midnight(): - DistrictPatientSummary() - print("Summarised Patients") diff --git a/care/facility/summarisation/facility_capacity.py b/care/facility/utils/summarisation/facility_capacity.py similarity index 67% rename from care/facility/summarisation/facility_capacity.py rename to care/facility/utils/summarisation/facility_capacity.py index 2122a0ce17..607e4535c6 100644 --- a/care/facility/summarisation/facility_capacity.py +++ b/care/facility/utils/summarisation/facility_capacity.py @@ -1,14 +1,5 @@ -from celery.decorators import periodic_task -from celery.schedules import crontab from django.db.models import Sum -from django.utils.decorators import method_decorator from django.utils.timezone import localtime, now -from django.views.decorators.cache import cache_page -from django_filters import rest_framework as filters -from rest_framework import serializers -from rest_framework.mixins import ListModelMixin -from rest_framework.permissions import IsAuthenticatedOrReadOnly -from rest_framework.viewsets import GenericViewSet from care.facility.api.serializers.facility import FacilitySerializer from care.facility.api.serializers.facility_capacity import FacilityCapacitySerializer @@ -25,64 +16,7 @@ ) -class FacilitySummarySerializer(serializers.ModelSerializer): - facility = FacilitySerializer() - - class Meta: - model = FacilityRelatedSummary - exclude = ( - "id", - "s_type", - ) - - -class FacilitySummaryFilter(filters.FilterSet): - start_date = filters.DateFilter(field_name="created_date", lookup_expr="gte") - end_date = filters.DateFilter(field_name="created_date", lookup_expr="lte") - facility = filters.UUIDFilter(field_name="facility__external_id") - district = filters.NumberFilter(field_name="facility__district__id") - local_body = filters.NumberFilter(field_name="facility__local_body__id") - state = filters.NumberFilter(field_name="facility__state__id") - - -class FacilityCapacitySummaryViewSet( - ListModelMixin, - GenericViewSet, -): - lookup_field = "external_id" - queryset = ( - FacilityRelatedSummary.objects.filter(s_type="FacilityCapacity") - .order_by("-created_date") - .select_related( - "facility", - "facility__state", - "facility__district", - "facility__local_body", - ) - ) - permission_classes = (IsAuthenticatedOrReadOnly,) - serializer_class = FacilitySummarySerializer - - filter_backends = (filters.DjangoFilterBackend,) - filterset_class = FacilitySummaryFilter - - @method_decorator(cache_page(60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - - # def get_queryset(self): - # user = self.request.user - # queryset = self.queryset - # if user.is_superuser: - # return queryset - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: - # return queryset.filter(facility__district=user.district) - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: - # return queryset.filter(facility__state=user.state) - # return queryset.filter(facility__users__id__exact=user.id) - - -def FacilityCapacitySummary(): +def facility_capacity_summary(): capacity_objects = FacilityCapacity.objects.all().select_related( "facility", "facility__state", @@ -140,17 +74,13 @@ def FacilityCapacitySummary(): Sum("quantity_in_default_unit") ) if temp1: - total_consumed = temp1.get("quantity_in_default_unit__sum", 0) - if not total_consumed: - total_consumed = 0 + total_consumed = temp1.get("quantity_in_default_unit__sum", 0) or 0 total_added = 0 temp2 = log_query.filter(is_incoming=True).aggregate( Sum("quantity_in_default_unit") ) if temp2: - total_added = temp2.get("quantity_in_default_unit__sum", 0) - if not total_added: - total_added = 0 + total_added = temp2.get("quantity_in_default_unit__sum", 0) or 0 # Calculate Start Stock as # end_stock = start_stock - consumption + addition @@ -207,9 +137,3 @@ def FacilityCapacitySummary(): facility_summary_obj.save() return True - - -@periodic_task(run_every=crontab(minute="*/5")) -def run_midnight(): - FacilityCapacitySummary() - print("Summarised Capacities") diff --git a/care/facility/summarisation/patient_summary.py b/care/facility/utils/summarisation/patient_summary.py similarity index 67% rename from care/facility/summarisation/patient_summary.py rename to care/facility/utils/summarisation/patient_summary.py index 63fb1e901e..3f3ca1a068 100644 --- a/care/facility/summarisation/patient_summary.py +++ b/care/facility/utils/summarisation/patient_summary.py @@ -1,50 +1,11 @@ -from celery.decorators import periodic_task -from celery.schedules import crontab from django.db.models import Q -from django.utils.decorators import method_decorator from django.utils.timezone import now -from django.views.decorators.cache import cache_page -from django_filters import rest_framework as filters -from rest_framework.mixins import ListModelMixin -from rest_framework.permissions import IsAuthenticatedOrReadOnly -from rest_framework.viewsets import GenericViewSet from care.facility.models import Facility, FacilityRelatedSummary, PatientRegistration from care.facility.models.patient_base import BedTypeChoices -from care.facility.summarisation.facility_capacity import ( - FacilitySummaryFilter, - FacilitySummarySerializer, -) -class PatientSummaryViewSet(ListModelMixin, GenericViewSet): - lookup_field = "external_id" - queryset = FacilityRelatedSummary.objects.filter(s_type="PatientSummary").order_by( - "-created_date" - ) - permission_classes = (IsAuthenticatedOrReadOnly,) - serializer_class = FacilitySummarySerializer - - filter_backends = (filters.DjangoFilterBackend,) - filterset_class = FacilitySummaryFilter - - @method_decorator(cache_page(60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - - # def get_queryset(self): - # user = self.request.user - # queryset = self.queryset - # if user.is_superuser: - # return queryset - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: - # return queryset.filter(facility__district=user.district) - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: - # return queryset.filter(facility__state=user.state) - # return queryset.filter(facility__users__id__exact=user.id) - - -def PatientSummary(): +def patient_summary(): facility_objects = Facility.objects.all() patient_summary = {} for facility_object in facility_objects: @@ -120,9 +81,7 @@ def PatientSummary(): ) facility.created_date = now() facility.data.pop("modified_date") - if facility.data == patient_summary[i]: - pass - else: + if facility.data != patient_summary[i]: facility.data = patient_summary[i] latest_modification_date = now() facility.data.update( @@ -142,9 +101,3 @@ def PatientSummary(): s_type="PatientSummary", facility_id=i, data=patient_summary[i] ).save() return True - - -@periodic_task(run_every=crontab(hour="*/1", minute=59)) -def run_midnight(): - PatientSummary() - print("Summarised Patients") diff --git a/care/facility/summarisation/tests_summary.py b/care/facility/utils/summarisation/tests_summary.py similarity index 52% rename from care/facility/summarisation/tests_summary.py rename to care/facility/utils/summarisation/tests_summary.py index 53e17d5bcb..4854a8fa5d 100644 --- a/care/facility/summarisation/tests_summary.py +++ b/care/facility/utils/summarisation/tests_summary.py @@ -1,46 +1,7 @@ -from celery.decorators import periodic_task -from celery.schedules import crontab from django.core.exceptions import ObjectDoesNotExist from django.utils import timezone -from django.utils.decorators import method_decorator -from django.views.decorators.cache import cache_page -from django_filters import rest_framework as filters -from rest_framework.mixins import ListModelMixin -from rest_framework.permissions import IsAuthenticatedOrReadOnly -from rest_framework.viewsets import GenericViewSet from care.facility.models import Facility, FacilityRelatedSummary, PatientSample -from care.facility.summarisation.facility_capacity import ( - FacilitySummaryFilter, - FacilitySummarySerializer, -) - - -class TestsSummaryViewSet(ListModelMixin, GenericViewSet): - lookup_field = "external_id" - queryset = FacilityRelatedSummary.objects.filter(s_type="TestSummary").order_by( - "-created_date" - ) - permission_classes = (IsAuthenticatedOrReadOnly,) - serializer_class = FacilitySummarySerializer - - filter_backends = (filters.DjangoFilterBackend,) - filterset_class = FacilitySummaryFilter - - # def get_queryset(self): - # user = self.request.user - # queryset = self.queryset - # if user.is_superuser: - # return queryset - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: - # return queryset.filter(facility__district=user.district) - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: - # return queryset.filter(facility__state=user.state) - # return queryset.filter(facility__users__id__exact=user.id) - - @method_decorator(cache_page(60 * 60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) def tests_summary(): @@ -84,29 +45,20 @@ def tests_summary(): ) facility_test_summary.created_date = timezone.now() facility_test_summary.data.pop("modified_date") - if not facility_test_summary.data == facility_tests_summarised_data: + if facility_test_summary.data != facility_tests_summarised_data: facility_test_summary.data = facility_tests_summarised_data latest_modification_date = timezone.now() - facility_test_summary.data.update( - { - "modified_date": latest_modification_date.strftime( - "%d-%m-%Y %H:%M" - ) - } - ) + facility_test_summary.data[ + "modified_date" + ] = latest_modification_date.strftime("%d-%m-%Y %H:%M") facility_test_summary.save() except ObjectDoesNotExist: modified_date = timezone.now() - facility_tests_summarised_data.update( - {"modified_date": modified_date.strftime("%d-%m-%Y %H:%M")} + facility_tests_summarised_data["modified_date"] = modified_date.strftime( + "%d-%m-%Y %H:%M" ) FacilityRelatedSummary.objects.create( s_type="TestSummary", facility=facility, data=facility_tests_summarised_data, ) - - -@periodic_task(run_every=crontab(hour=23, minute=59)) -def run_midnight(): - tests_summary() diff --git a/care/facility/summarisation/triage_summary.py b/care/facility/utils/summarisation/triage_summary.py similarity index 67% rename from care/facility/summarisation/triage_summary.py rename to care/facility/utils/summarisation/triage_summary.py index 2f7702002d..df5f4a296c 100644 --- a/care/facility/summarisation/triage_summary.py +++ b/care/facility/utils/summarisation/triage_summary.py @@ -1,53 +1,14 @@ -from celery.decorators import periodic_task -from celery.schedules import crontab from django.db.models import Count, Sum -from django.utils.decorators import method_decorator from django.utils.timezone import localtime, now -from django.views.decorators.cache import cache_page -from django_filters import rest_framework as filters -from rest_framework.mixins import ListModelMixin -from rest_framework.permissions import IsAuthenticatedOrReadOnly -from rest_framework.viewsets import GenericViewSet from care.facility.models import ( Facility, FacilityPatientStatsHistory, FacilityRelatedSummary, ) -from care.facility.summarisation.facility_capacity import ( - FacilitySummaryFilter, - FacilitySummarySerializer, -) - - -class TriageSummaryViewSet(ListModelMixin, GenericViewSet): - lookup_field = "external_id" - queryset = FacilityRelatedSummary.objects.filter(s_type="TriageSummary").order_by( - "-created_date" - ) - permission_classes = (IsAuthenticatedOrReadOnly,) - serializer_class = FacilitySummarySerializer - - filter_backends = (filters.DjangoFilterBackend,) - filterset_class = FacilitySummaryFilter - # def get_queryset(self): - # user = self.request.user - # queryset = self.queryset - # if user.is_superuser: - # return queryset - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["DistrictReadOnlyAdmin"]: - # return queryset.filter(facility__district=user.district) - # elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateReadOnlyAdmin"]: - # return queryset.filter(facility__state=user.state) - # return queryset.filter(facility__users__id__exact=user.id) - @method_decorator(cache_page(60 * 60 * 1)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - - -def TriageSummary(): +def triage_summary(): facilities = Facility.objects.all() current_date = localtime(now()).replace(hour=0, minute=0, second=0, microsecond=0) for facility in facilities: @@ -122,8 +83,3 @@ def TriageSummary(): data=facility_triage_summarised_data, ) facility_triage_summary.save() - - -@periodic_task(run_every=crontab(hour="*/4", minute=59)) -def run_midnight(): - TriageSummary() diff --git a/care/hcx/api/viewsets/gateway.py b/care/hcx/api/viewsets/gateway.py index 4c4651803e..34d9835a0e 100644 --- a/care/hcx/api/viewsets/gateway.py +++ b/care/hcx/api/viewsets/gateway.py @@ -14,9 +14,7 @@ from care.facility.models.file_upload import FileUpload from care.facility.models.patient_consultation import PatientConsultation from care.facility.static_data.icd11 import ICDDiseases -from care.facility.tasks.patient.discharge_report import ( - generate_discharge_report_signed_url, -) +from care.facility.tasks.discharge_report import generate_discharge_report_signed_url from care.hcx.api.serializers.claim import ClaimSerializer from care.hcx.api.serializers.gateway import ( CheckEligibilitySerializer, diff --git a/care/utils/notification_handler.py b/care/utils/notification_handler.py index 052157686b..677eb132d4 100644 --- a/care/utils/notification_handler.py +++ b/care/utils/notification_handler.py @@ -1,6 +1,6 @@ import json -import celery +from celery import shared_task from django.apps import apps from django.conf import settings from pywebpush import WebPushException, webpush @@ -23,12 +23,12 @@ class NotificationCreationException(Exception): pass -@celery.task() +@shared_task def notification_task_generator(**kwargs): NotificationGenerator(**kwargs).generate() -@celery.task() +@shared_task def send_webpush(**kwargs): user = User.objects.get(username=kwargs.get("username")) message = kwargs.get("message") diff --git a/config/api_router.py b/config/api_router.py index 83aed2b502..8d60ce3f8d 100644 --- a/config/api_router.py +++ b/config/api_router.py @@ -66,13 +66,13 @@ ShifitngRequestCommentViewSet, ShiftingViewSet, ) -from care.facility.summarisation.district.patient_summary import ( +from care.facility.api.viewsets.summary import ( DistrictPatientSummaryViewSet, + FacilityCapacitySummaryViewSet, + PatientSummaryViewSet, + TestsSummaryViewSet, + TriageSummaryViewSet, ) -from care.facility.summarisation.facility_capacity import FacilityCapacitySummaryViewSet -from care.facility.summarisation.patient_summary import PatientSummaryViewSet -from care.facility.summarisation.tests_summary import TestsSummaryViewSet -from care.facility.summarisation.triage_summary import TriageSummaryViewSet from care.hcx.api.viewsets.claim import ClaimViewSet from care.hcx.api.viewsets.gateway import HcxGatewayViewSet from care.hcx.api.viewsets.policy import PolicyViewSet diff --git a/config/settings/base.py b/config/settings/base.py index 6261f777df..a63ad31fca 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -356,28 +356,26 @@ # Celery (background tasks) # ------------------------------------------------------------------------------ -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-timezone +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-timezone if USE_TZ: - # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-timezone + # https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-timezone CELERY_TIMEZONE = TIME_ZONE -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-broker_url +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-broker_url CELERY_BROKER_URL = env("CELERY_BROKER_URL", default="redis://localhost:6379/0") -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-result_backend +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-result_backend CELERY_RESULT_BACKEND = CELERY_BROKER_URL -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-accept_content +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-accept_content CELERY_ACCEPT_CONTENT = ["json"] -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-task_serializer +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-task_serializer CELERY_TASK_SERIALIZER = "json" -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-result_serializer +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-result_serializer CELERY_RESULT_SERIALIZER = "json" -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-time-limit +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#task-time-limit # TODO: set to whatever value is adequate in your circumstances CELERY_TASK_TIME_LIMIT = 1800 * 5 -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-soft-time-limit +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#task-soft-time-limit # TODO: set to whatever value is adequate in your circumstances CELERY_TASK_SOFT_TIME_LIMIT = 1800 -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#beat-scheduler -CELERY_TIMEZONE = "Asia/Kolkata" # Maintenance Mode # ------------------------------------------------------------------------------ diff --git a/config/settings/local.py b/config/settings/local.py index 6cd8d12b2d..f4fb98eb85 100644 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -28,7 +28,7 @@ # Celery # ------------------------------------------------------------------------------ -# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-eager-propagates +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#task-eager-propagates CELERY_TASK_EAGER_PROPAGATES = True diff --git a/requirements/base.txt b/requirements/base.txt index 7723cc74be..4eeaff3eee 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -43,7 +43,7 @@ littletable==2.0.7 # Asyncronous Part # ------------------------------------------------------------------------------ -celery==4.4.2 +celery==5.3.0 # https://docs.celeryq.dev/en/latest/changelog.html # WebPushes # ------------------------------------------------------------------------------ From 40ff4445efe6cdd825ff8245e6e93a40e4e22856 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 13:21:20 +0530 Subject: [PATCH 12/24] fix tests --- care/facility/tests/test_delete_older_notifications_task.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/care/facility/tests/test_delete_older_notifications_task.py b/care/facility/tests/test_delete_older_notifications_task.py index bfbc5606a5..9f860770b2 100644 --- a/care/facility/tests/test_delete_older_notifications_task.py +++ b/care/facility/tests/test_delete_older_notifications_task.py @@ -5,9 +5,7 @@ from freezegun import freeze_time from care.facility.models.notification import Notification -from care.facility.tasks.notification.delete_older_notifications import ( - delete_old_notifications, -) +from care.facility.tasks.cleanup import delete_old_notifications class DeleteOldNotificationsTest(TestCase): From 697ddd974703c8eaf59a1aaf2e3f8d77c12c44bb Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 13:36:40 +0530 Subject: [PATCH 13/24] fix migration edge cases --- config/settings/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/settings/base.py b/config/settings/base.py index a63ad31fca..d3fc10c6b2 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -111,8 +111,8 @@ "healthy_django", ] LOCAL_APPS = [ - "care.users", "care.facility", + "care.users", "care.audit_log", "care.hcx", ] From 0e440c7ad13623712baa4b26d626f1a2da856f43 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 13:38:34 +0530 Subject: [PATCH 14/24] update fixtures --- data/dummy/facility.json | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/data/dummy/facility.json b/data/dummy/facility.json index 4900a68c7a..6ffac9c1e0 100644 --- a/data/dummy/facility.json +++ b/data/dummy/facility.json @@ -712,27 +712,6 @@ "assigned_to": null } }, - { - "model": "facility.patientsearch", - "pk": 1, - "fields": { - "external_id": "869f3429-ac7f-423e-8f55-9371fc89ff16", - "created_date": "2022-09-27T07:19:20.394Z", - "modified_date": "2022-09-27T07:19:20.394Z", - "deleted": false, - "patient_id": 1, - "name": "Dummy Patient", - "gender": 1, - "phone_number": "+911234567896", - "date_of_birth": "1901-10-16", - "year_of_birth": 1901, - "state_id": 1, - "facility": 1, - "patient_external_id": "7c1d2896-8ebf-45c7-b507-98fcedd48ef3", - "allow_transfer": true, - "is_active": true - } - }, { "model": "facility.disease", "pk": 1, From 76abf852f98f102ab129bcc94d2cfe1c9c317263 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 22:37:11 +0530 Subject: [PATCH 15/24] reduce db connection max age to prevent exhausting connections in devserver mode --- config/settings/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index d3fc10c6b2..3c2ab5b601 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -55,7 +55,7 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = {"default": env.db("DATABASE_URL", default="postgres:///care")} DATABASES["default"]["ATOMIC_REQUESTS"] = True -DATABASES["default"]["CONN_MAX_AGE"] = 300 +DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=30) DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # CACHES @@ -316,7 +316,7 @@ # https://www.django-rest-framework.org/api-guide/settings/ REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( - # "rest_framework.authentication.BasicAuthentication", + "rest_framework.authentication.BasicAuthentication", # Primary api authentication # "rest_framework_simplejwt.authentication.JWTAuthentication", "config.authentication.CustomJWTAuthentication", From 147425786c1cfad2c4d788158192a2eda982bdae Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 22:43:34 +0530 Subject: [PATCH 16/24] fix test cases --- care/facility/tests/test_facility_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/care/facility/tests/test_facility_api.py b/care/facility/tests/test_facility_api.py index fc3a8c967c..a132186627 100644 --- a/care/facility/tests/test_facility_api.py +++ b/care/facility/tests/test_facility_api.py @@ -56,7 +56,7 @@ def test_no_auth(self): {"get": "list"}, FacilityViewSet, ) - self.assertIs(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertIs(response.status_code, status.HTTP_401_UNAUTHORIZED) sample_data = {} create_response = self.new_request( @@ -64,4 +64,4 @@ def test_no_auth(self): {"post": "create"}, FacilityViewSet, ) - self.assertIs(create_response.status_code, status.HTTP_403_FORBIDDEN) + self.assertIs(create_response.status_code, status.HTTP_401_UNAUTHORIZED) From ca90ddc416667551d9ca208188d7ed0ab2874742 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Thu, 15 Jun 2023 23:33:59 +0530 Subject: [PATCH 17/24] cypress is still too fast for devserver --- config/settings/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/settings/base.py b/config/settings/base.py index 3c2ab5b601..23cc0f98ab 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -55,7 +55,7 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = {"default": env.db("DATABASE_URL", default="postgres:///care")} DATABASES["default"]["ATOMIC_REQUESTS"] = True -DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=30) +DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=0) DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # CACHES From 34f6a46471b841f06343ba00de0fd43adadb053d Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Sat, 17 Jun 2023 12:43:50 +0530 Subject: [PATCH 18/24] update api schema groups --- care/facility/api/serializers/asset.py | 40 ++++++++++++- .../api/serializers/patient_investigation.py | 11 ++++ care/facility/api/viewsets/ambulance.py | 4 ++ care/facility/api/viewsets/asset.py | 43 +++----------- care/facility/api/viewsets/bed.py | 2 + care/facility/api/viewsets/daily_round.py | 2 + care/facility/api/viewsets/facility.py | 7 +++ .../api/viewsets/facility_capacity.py | 2 + care/facility/api/viewsets/facility_users.py | 2 + care/facility/api/viewsets/inventory.py | 3 + care/facility/api/viewsets/notification.py | 2 + care/facility/api/viewsets/open_id.py | 8 +++ care/facility/api/viewsets/patient.py | 4 ++ .../api/viewsets/patient_consultation.py | 12 ++-- .../api/viewsets/patient_external_test.py | 2 + .../api/viewsets/patient_investigation.py | 18 +++--- care/facility/api/viewsets/patient_otp.py | 3 + care/facility/api/viewsets/prescription.py | 8 ++- care/facility/api/viewsets/shifting.py | 2 + care/facility/api/viewsets/summary.py | 28 +++++---- care/users/api/viewsets/change_password.py | 8 ++- care/users/api/viewsets/lsg.py | 20 +++++++ care/users/api/viewsets/users.py | 23 +++----- care/users/reset_password_views.py | 4 ++ config/auth_views.py | 34 ++++++++++- config/authentication.py | 57 +++++++++++++++++++ config/settings/base.py | 3 +- config/urls.py | 9 ++- 28 files changed, 274 insertions(+), 87 deletions(-) diff --git a/care/facility/api/serializers/asset.py b/care/facility/api/serializers/asset.py index d209412ccb..c14e7c8751 100644 --- a/care/facility/api/serializers/asset.py +++ b/care/facility/api/serializers/asset.py @@ -1,10 +1,17 @@ +import enum from datetime import datetime from django.core.cache import cache from django.db import transaction from django.shortcuts import get_object_or_404 from rest_framework.exceptions import ValidationError -from rest_framework.serializers import ModelSerializer, UUIDField +from rest_framework.serializers import ( + CharField, + JSONField, + ModelSerializer, + Serializer, + UUIDField, +) from rest_framework.validators import UniqueValidator from care.facility.api.serializers import TIMESTAMP_FIELDS @@ -16,6 +23,9 @@ UserDefaultAssetLocation, ) from care.users.api.serializers.user import UserBaseMinimumSerializer +from care.utils.assetintegration.hl7monitor import HL7MonitorAsset +from care.utils.assetintegration.onvif import OnvifAsset +from care.utils.assetintegration.ventilator import VentilatorAsset from care.utils.queryset.facility import get_facility_queryset from config.serializers import ChoiceField @@ -161,3 +171,31 @@ class UserDefaultAssetLocationSerializer(ModelSerializer): class Meta: model = UserDefaultAssetLocation exclude = ("deleted", "external_id", "location", "user", "id") + + +class AssetActionSerializer(Serializer): + def actionChoices(): + actions: list[enum.Enum] = [ + OnvifAsset.OnvifActions, + HL7MonitorAsset.HL7MonitorActions, + VentilatorAsset.VentilatorActions, + ] + choices = [] + for action in actions: + choices += [(e.value, e.name) for e in action] + return choices + + type = ChoiceField( + choices=actionChoices(), + required=True, + ) + data = JSONField(required=False) + + +class DummyAssetOperateSerializer(Serializer): + action = AssetActionSerializer(required=True) + + +class DummyAssetOperateResponseSerializer(Serializer): + message = CharField(required=True) + result = JSONField(required=False) diff --git a/care/facility/api/serializers/patient_investigation.py b/care/facility/api/serializers/patient_investigation.py index 1a64070ec5..aa97b42535 100644 --- a/care/facility/api/serializers/patient_investigation.py +++ b/care/facility/api/serializers/patient_investigation.py @@ -81,3 +81,14 @@ class Meta: model = InvestigationValue read_only_fields = TIMESTAMP_FIELDS exclude = TIMESTAMP_FIELDS + ("external_id",) + + +class ValueSerializer(serializers.ModelSerializer): + class Meta: + model = InvestigationValue + fields = ("external_id", "value", "notes") + + +# Dummy for Spec +class InvestigationUpdateSerializer(serializers.Serializer): + investigations = ValueSerializer(many=True) diff --git a/care/facility/api/viewsets/ambulance.py b/care/facility/api/viewsets/ambulance.py index 6559762797..99ced76c6b 100644 --- a/care/facility/api/viewsets/ambulance.py +++ b/care/facility/api/viewsets/ambulance.py @@ -1,4 +1,5 @@ from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import serializers, status from rest_framework.decorators import action from rest_framework.mixins import ( @@ -54,6 +55,7 @@ class AmbulanceViewSet( filter_backends = (filters.DjangoFilterBackend,) filterset_class = AmbulanceFilterSet + @extend_schema(tags=["ambulance"]) @action(methods=["POST"], detail=True) def add_driver(self, request): ambulance = self.get_object() @@ -66,6 +68,7 @@ def add_driver(self, request): status=status.HTTP_201_CREATED, ) + @extend_schema(tags=["ambulance"]) @action(methods=["DELETE"], detail=True) def remove_driver(self, request): class DeleteDriverSerializer(serializers.Serializer): @@ -91,6 +94,7 @@ def create(self, validated_data): return Response(status=status.HTTP_204_NO_CONTENT) +@extend_schema_view(create=extend_schema(tags=["ambulance"])) class AmbulanceCreateViewSet(CreateModelMixin, GenericViewSet): permission_classes = (IsAuthenticated,) serializer_class = AmbulanceSerializer diff --git a/care/facility/api/viewsets/asset.py b/care/facility/api/viewsets/asset.py index 2196b2e28d..a156c1e464 100644 --- a/care/facility/api/viewsets/asset.py +++ b/care/facility/api/viewsets/asset.py @@ -1,5 +1,3 @@ -import enum - from django.core.cache import cache from django.db.models import Q from django.http import Http404 @@ -21,13 +19,15 @@ ) from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from rest_framework.serializers import CharField, JSONField, Serializer, UUIDField +from rest_framework.serializers import Serializer, UUIDField from rest_framework.viewsets import GenericViewSet from care.facility.api.serializers.asset import ( AssetLocationSerializer, AssetSerializer, AssetTransactionSerializer, + DummyAssetOperateResponseSerializer, + DummyAssetOperateSerializer, UserDefaultAssetLocationSerializer, ) from care.facility.models.asset import ( @@ -39,14 +39,10 @@ from care.users.models import User from care.utils.assetintegration.asset_classes import AssetClasses from care.utils.assetintegration.base import BaseAssetIntegration -from care.utils.assetintegration.hl7monitor import HL7MonitorAsset -from care.utils.assetintegration.onvif import OnvifAsset -from care.utils.assetintegration.ventilator import VentilatorAsset from care.utils.cache.cache_allowed_facilities import get_accessible_facilities from care.utils.filters.choicefilter import CareChoiceFilter, inverse_choices from care.utils.queryset.asset_location import get_asset_location_queryset from care.utils.queryset.facility import get_facility_queryset -from config.serializers import ChoiceField inverse_asset_type = inverse_choices(Asset.AssetTypeChoices) inverse_asset_status = inverse_choices(Asset.StatusChoices) @@ -179,7 +175,9 @@ def destroy(self, request, *args, **kwargs): "Only District Admin and above can delete assets" ) - @extend_schema(responses={200: UserDefaultAssetLocationSerializer()}) + @extend_schema( + responses={200: UserDefaultAssetLocationSerializer()}, tags=["asset"] + ) @action(detail=False, methods=["GET"]) def get_default_user_location(self, request, *args, **kwargs): obj = get_object_or_404( @@ -193,6 +191,7 @@ class DummyAssetSerializer(Serializer): # Dummy for Spec @extend_schema( request=DummyAssetSerializer, responses={200: UserDefaultAssetLocationSerializer()}, + tags=["asset"], ) @action(detail=False, methods=["POST"]) def set_default_user_location(self, request, *args, **kwargs): @@ -211,36 +210,10 @@ def set_default_user_location(self, request, *args, **kwargs): except Exception as e: raise Http404 from e - # Dummy Serializer for Operate Asset - class DummyAssetOperateSerializer(Serializer): - class AssetActionSerializer(Serializer): - def actionChoices(): - actions: list[enum.Enum] = [ - OnvifAsset.OnvifActions, - HL7MonitorAsset.HL7MonitorActions, - VentilatorAsset.VentilatorActions, - ] - choices = [] - for action in actions: - choices += [(e.value, e.name) for e in action] - return choices - - type = ChoiceField( - choices=actionChoices(), - required=True, - ) - data = JSONField(required=False) - - action = AssetActionSerializer(required=True) - - class DummyAssetOperateResponseSerializer(Serializer): - message = CharField(required=True) - result = JSONField(required=False) - - # Asset Integration API @extend_schema( request=DummyAssetOperateSerializer, responses={200: DummyAssetOperateResponseSerializer}, + tags=["asset"], ) @action(detail=True, methods=["POST"]) def operate_assets(self, request, *args, **kwargs): diff --git a/care/facility/api/viewsets/bed.py b/care/facility/api/viewsets/bed.py index cfa98e8888..9b6b43389c 100644 --- a/care/facility/api/viewsets/bed.py +++ b/care/facility/api/viewsets/bed.py @@ -1,6 +1,7 @@ from django.core.exceptions import ValidationError as DjangoValidationError from django.db.models import OuterRef, Subquery from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import filters as drf_filters from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import ValidationError as DRFValidationError @@ -138,6 +139,7 @@ def filter_bed_is_occupied(self, queryset, name, value): ) +@extend_schema_view(list=extend_schema(tags=["facility"])) class PatientAssetBedViewSet(ListModelMixin, GenericViewSet): queryset = AssetBed.objects.select_related("asset", "bed").order_by("-created_date") serializer_class = PatientAssetBedSerializer diff --git a/care/facility/api/viewsets/daily_round.py b/care/facility/api/viewsets/daily_round.py index cbf93168bb..387c5489a3 100644 --- a/care/facility/api/viewsets/daily_round.py +++ b/care/facility/api/viewsets/daily_round.py @@ -1,4 +1,5 @@ from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissions from rest_framework import mixins from rest_framework.decorators import action @@ -66,6 +67,7 @@ def get_serializer(self, *args, **kwargs): ).id return super().get_serializer(*args, **kwargs) + @extend_schema(tags=["daily_rounds"]) @action(methods=["POST"], detail=False) def analyse(self, request, **kwargs): # Request Body Validations diff --git a/care/facility/api/viewsets/facility.py b/care/facility/api/viewsets/facility.py index ebf0ee46ab..8e4f4bd3f7 100644 --- a/care/facility/api/viewsets/facility.py +++ b/care/facility/api/viewsets/facility.py @@ -1,6 +1,7 @@ from django.conf import settings from django_filters import rest_framework as filters from djqscsv import render_to_csv_response +from drf_spectacular.utils import extend_schema, extend_schema_view from dry_rest_permissions.generics import DRYPermissionFiltersBase, DRYPermissions from rest_framework import filters as drf_filters from rest_framework import mixins, status, viewsets @@ -141,6 +142,7 @@ def list(self, request, *args, **kwargs): return super(FacilityViewSet, self).list(request, *args, **kwargs) + @extend_schema(tags=["facility"]) @action(methods=["POST"], detail=True) def cover_image(self, request, external_id): facility = self.get_object() @@ -149,6 +151,7 @@ def cover_image(self, request, external_id): serializer.save() return Response(serializer.data) + @extend_schema(tags=["facility"]) @cover_image.mapping.delete def cover_image_delete(self, *args, **kwargs): facility = self.get_object() @@ -157,6 +160,10 @@ def cover_image_delete(self, *args, **kwargs): return Response(status=status.HTTP_204_NO_CONTENT) +@extend_schema_view( + list=extend_schema(tags=["facility"]), + retrieve=extend_schema(tags=["facility"]), +) class AllFacilityViewSet( mixins.RetrieveModelMixin, mixins.ListModelMixin, diff --git a/care/facility/api/viewsets/facility_capacity.py b/care/facility/api/viewsets/facility_capacity.py index 6515efb3b7..cfb92ef8b7 100644 --- a/care/facility/api/viewsets/facility_capacity.py +++ b/care/facility/api/viewsets/facility_capacity.py @@ -1,3 +1,4 @@ +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissions from rest_framework.decorators import action from rest_framework.generics import get_object_or_404 @@ -51,6 +52,7 @@ def get_facility(self): def perform_create(self, serializer): serializer.save(facility=self.get_facility()) + @extend_schema(tags=["capacity"]) @action(detail=True, methods=["get"]) def history(self, request, *args, **kwargs): obj = self.get_object() diff --git a/care/facility/api/viewsets/facility_users.py b/care/facility/api/viewsets/facility_users.py index 6631f44b8d..8422991791 100644 --- a/care/facility/api/viewsets/facility_users.py +++ b/care/facility/api/viewsets/facility_users.py @@ -1,4 +1,5 @@ from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import mixins from rest_framework.exceptions import ValidationError from rest_framework.permissions import IsAuthenticated @@ -20,6 +21,7 @@ class Meta: fields = [] +@extend_schema_view(list=extend_schema(tags=["facility", "users"])) class FacilityUserViewSet(GenericViewSet, mixins.ListModelMixin): serializer_class = UserAssignedSerializer filterset_class = UserFilter diff --git a/care/facility/api/viewsets/inventory.py b/care/facility/api/viewsets/inventory.py index c43dada5fe..3453c6c3b4 100644 --- a/care/facility/api/viewsets/inventory.py +++ b/care/facility/api/viewsets/inventory.py @@ -1,5 +1,6 @@ from django.db import transaction from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissions from rest_framework import status from rest_framework.decorators import action @@ -104,6 +105,7 @@ def get_facility(self): queryset.filter(external_id=self.kwargs.get("facility_external_id")) ) + @extend_schema(tags=["inventory"]) @action(methods=["PUT"], detail=True) def flag(self, request, **kwargs): log_obj = get_object_or_404( @@ -114,6 +116,7 @@ def flag(self, request, **kwargs): set_burn_rate(log_obj.facility, log_obj.item) return Response(status=status.HTTP_204_NO_CONTENT) + @extend_schema(tags=["inventory"]) @action(methods=["DELETE"], detail=False) def delete_last(self, request, **kwargs): facility = self.get_facility() diff --git a/care/facility/api/viewsets/notification.py b/care/facility/api/viewsets/notification.py index 0f608c826d..35d4a76e78 100644 --- a/care/facility/api/viewsets/notification.py +++ b/care/facility/api/viewsets/notification.py @@ -46,6 +46,7 @@ def get_queryset(self): user = self.request.user return self.queryset.filter(intended_for=user) + @extend_schema(tags=["notification"]) @action( detail=False, methods=["GET"], permission_classes=[IsAuthenticatedOrReadOnly] ) @@ -59,6 +60,7 @@ class DummyNotificationSerializer(Serializer): # Dummy for Spec @extend_schema( request=DummyNotificationSerializer, responses={204: "Notification Processed"}, + tags=["notification"], ) @action(detail=False, methods=["POST"]) def notify(self, request, *args, **kwargs): diff --git a/care/facility/api/viewsets/open_id.py b/care/facility/api/viewsets/open_id.py index cd53259aa3..f131eafe3f 100644 --- a/care/facility/api/viewsets/open_id.py +++ b/care/facility/api/viewsets/open_id.py @@ -1,8 +1,16 @@ from django.conf import settings from rest_framework.generics import GenericAPIView +from rest_framework.permissions import AllowAny from rest_framework.response import Response class OpenIdConfigView(GenericAPIView): + """ + Retrieve the OpenID Connect configuration + """ + + authentication_classes = () + permission_classes = (AllowAny,) + def get(self, *args, **kwargs): return Response(settings.JWKS.as_dict()) diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index f9ccf342e0..e55fa3443e 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -9,6 +9,7 @@ from django.db.models.query_utils import Q from django_filters import rest_framework as filters from djqscsv import render_to_csv_response +from drf_spectacular.utils import extend_schema, extend_schema_view from dry_rest_permissions.generics import DRYPermissionFiltersBase, DRYPermissions from rest_framework import filters as rest_framework_filters from rest_framework import mixins, serializers, status, viewsets @@ -242,6 +243,7 @@ def filter_queryset(self, request, queryset, view): return queryset +@extend_schema_view(history=extend_schema(tags=["patient"])) class PatientViewSet( HistoryMixin, mixins.CreateModelMixin, @@ -393,6 +395,7 @@ def list(self, request, *args, **kwargs): return super(PatientViewSet, self).list(request, *args, **kwargs) + @extend_schema(tags=["patient"]) @action(detail=True, methods=["POST"]) def transfer(self, request, *args, **kwargs): patient = PatientRegistration.objects.get(external_id=kwargs["external_id"]) @@ -552,6 +555,7 @@ def get_queryset(self): return queryset + @extend_schema(tags=["patient"]) def list(self, request, *args, **kwargs): """ Patient Search diff --git a/care/facility/api/viewsets/patient_consultation.py b/care/facility/api/viewsets/patient_consultation.py index c63cc7b02c..736b6e3d76 100644 --- a/care/facility/api/viewsets/patient_consultation.py +++ b/care/facility/api/viewsets/patient_consultation.py @@ -85,6 +85,7 @@ def get_queryset(self): applied_filters |= Q(patient__assigned_to=self.request.user) return self.queryset.filter(applied_filters) + @extend_schema(tags=["consultation"]) @action(detail=True, methods=["POST"]) def discharge_patient(self, request, *args, **kwargs): consultation = self.get_object() @@ -99,6 +100,7 @@ def discharge_patient(self, request, *args, **kwargs): responses={ 200: "Success", }, + tags=["consultation"], ) @action(detail=True, methods=["POST"]) def generate_discharge_summary(self, request, *args, **kwargs): @@ -109,9 +111,8 @@ def generate_discharge_summary(self, request, *args, **kwargs): @extend_schema( description="Get the discharge summary", - responses={ - 200: "Success", - }, + responses={200: "Success"}, + tags=["consultation"], ) @action(detail=True, methods=["GET"]) def preview_discharge_summary(self, request, *args, **kwargs): @@ -134,6 +135,7 @@ def preview_discharge_summary(self, request, *args, **kwargs): description="Email the discharge summary to the user", request=EmailDischargeSummarySerializer, responses={200: "Success"}, + tags=["consultation"], ) @action(detail=True, methods=["POST"]) def email_discharge_summary(self, request, *args, **kwargs): @@ -148,7 +150,9 @@ def email_discharge_summary(self, request, *args, **kwargs): email_discharge_summary.delay(consultation.external_id, email) return Response(status=status.HTTP_200_OK) - @extend_schema(responses={200: PatientConsultationIDSerializer}) + @extend_schema( + responses={200: PatientConsultationIDSerializer}, tags=["consultation", "asset"] + ) @action(detail=False, methods=["GET"]) def patient_from_asset(self, request): consultation = ( diff --git a/care/facility/api/viewsets/patient_external_test.py b/care/facility/api/viewsets/patient_external_test.py index 53b63305a9..422d0bb512 100644 --- a/care/facility/api/viewsets/patient_external_test.py +++ b/care/facility/api/viewsets/patient_external_test.py @@ -5,6 +5,7 @@ from django_filters import rest_framework as filters from django_filters.filters import DateFromToRangeFilter from djqscsv import render_to_csv_response +from drf_spectacular.utils import extend_schema from rest_framework import status from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied, ValidationError @@ -128,6 +129,7 @@ def list(self, request, *args, **kwargs): ) return super(PatientExternalTestViewSet, self).list(request, *args, **kwargs) + @extend_schema(tags=["external_result"]) @action(methods=["POST"], detail=False) def bulk_upsert(self, request, *args, **kwargs): if not self.check_upload_permission(): diff --git a/care/facility/api/viewsets/patient_investigation.py b/care/facility/api/viewsets/patient_investigation.py index e24c839955..f575a33fe2 100644 --- a/care/facility/api/viewsets/patient_investigation.py +++ b/care/facility/api/viewsets/patient_investigation.py @@ -6,15 +6,15 @@ from django_filters import Filter from django_filters import rest_framework as filters from drf_spectacular.utils import extend_schema -from rest_framework import mixins, serializers, status, viewsets +from rest_framework import mixins, status, viewsets from rest_framework.decorators import action from rest_framework.exceptions import ValidationError from rest_framework.pagination import PageNumberPagination from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from rest_framework.serializers import Serializer from care.facility.api.serializers.patient_investigation import ( + InvestigationUpdateSerializer, InvestigationValueCreateSerializer, InvestigationValueSerializer, PatientInvestigationGroupSerializer, @@ -188,7 +188,10 @@ def get_queryset(self): filters |= Q(consultation__patient__assigned_to=self.request.user) return queryset.filter(filters).distinct("id") - @extend_schema(responses={200: PatientInvestigationSessionSerializer(many=True)}) + @extend_schema( + responses={200: PatientInvestigationSessionSerializer(many=True)}, + tags=["investigation"], + ) @action(detail=False, methods=["GET"]) def get_sessions(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) @@ -203,17 +206,10 @@ def get_sessions(self, request, *args, **kwargs): ) ) - class InvestigationUpdateSerializer(Serializer): # Dummy for Spec - class ValueSerializer(serializers.ModelSerializer): - class Meta: - model = InvestigationValue - fields = ("external_id", "value", "notes") - - investigations = ValueSerializer(many=True) - @extend_schema( request=InvestigationUpdateSerializer, responses={204: "Operation successful"}, + tags=["investigation"], ) @action(detail=False, methods=["PUT"]) def batchUpdate(self, request, *args, **kwargs): diff --git a/care/facility/api/viewsets/patient_otp.py b/care/facility/api/viewsets/patient_otp.py index fe0d8aa347..d2efa9ddcd 100644 --- a/care/facility/api/viewsets/patient_otp.py +++ b/care/facility/api/viewsets/patient_otp.py @@ -1,6 +1,7 @@ from re import error from django.conf import settings +from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import mixins from rest_framework.decorators import action from rest_framework.exceptions import ValidationError @@ -14,6 +15,7 @@ from config.patient_otp_token import PatientToken +@extend_schema_view(create=extend_schema(tags=["auth"])) class PatientMobileOTPViewSet( mixins.CreateModelMixin, GenericViewSet, @@ -22,6 +24,7 @@ class PatientMobileOTPViewSet( serializer_class = PatientMobileOTPSerializer queryset = PatientMobileOTP.objects.all() + @extend_schema(tags=["auth"]) @action(detail=False, methods=["POST"]) def login(self, request): if "phone_number" not in request.data or "otp" not in request.data: diff --git a/care/facility/api/viewsets/prescription.py b/care/facility/api/viewsets/prescription.py index 847780a157..e89bfde5a1 100644 --- a/care/facility/api/viewsets/prescription.py +++ b/care/facility/api/viewsets/prescription.py @@ -1,5 +1,6 @@ from django.shortcuts import get_object_or_404 from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema from rest_framework import mixins, status from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated @@ -89,7 +90,11 @@ def perform_create(self, serializer): consultation_obj = self.get_consultation_obj() serializer.save(prescribed_by=self.request.user, consultation=consultation_obj) - @action(methods=["POST"], detail=True) + @extend_schema(tags=["prescriptions"]) + @action( + methods=["POST"], + detail=True, + ) def discontinue(self, request, *args, **kwargs): prescription_obj = self.get_object() prescription_obj.discontinued = True @@ -99,6 +104,7 @@ def discontinue(self, request, *args, **kwargs): prescription_obj.save() return Response({}, status=status.HTTP_201_CREATED) + @extend_schema(tags=["prescriptions"]) @action( methods=["POST"], detail=True, diff --git a/care/facility/api/viewsets/shifting.py b/care/facility/api/viewsets/shifting.py index cdc4084c33..7bb67cb56d 100644 --- a/care/facility/api/viewsets/shifting.py +++ b/care/facility/api/viewsets/shifting.py @@ -3,6 +3,7 @@ from django.utils.timezone import localtime, now from django_filters import rest_framework as filters from djqscsv import render_to_csv_response +from drf_spectacular.utils import extend_schema from dry_rest_permissions.generics import DRYPermissionFiltersBase, DRYPermissions from rest_framework import filters as rest_framework_filters from rest_framework import mixins, status @@ -135,6 +136,7 @@ def get_serializer_class(self): serializer_class = ShiftingDetailSerializer return serializer_class + @extend_schema(tags=["shift"]) @action(detail=True, methods=["POST"]) def transfer(self, request, *args, **kwargs): shifting_obj = self.get_object() diff --git a/care/facility/api/viewsets/summary.py b/care/facility/api/viewsets/summary.py index 11b7976fa9..e223a204c4 100644 --- a/care/facility/api/viewsets/summary.py +++ b/care/facility/api/viewsets/summary.py @@ -1,6 +1,7 @@ from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema from rest_framework.mixins import ListModelMixin from rest_framework.permissions import IsAuthenticatedOrReadOnly from rest_framework.viewsets import GenericViewSet @@ -42,9 +43,10 @@ class FacilityCapacitySummaryViewSet( filter_backends = (filters.DjangoFilterBackend,) filterset_class = FacilitySummaryFilter + @extend_schema(tags=["summary"]) @method_decorator(cache_page(60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def list(self, request, *args, **kwargs): + return super().list(request, *args, **kwargs) # def get_queryset(self): # user = self.request.user @@ -80,9 +82,10 @@ class TriageSummaryViewSet(ListModelMixin, GenericViewSet): # return queryset.filter(facility__state=user.state) # return queryset.filter(facility__users__id__exact=user.id) - @method_decorator(cache_page(60 * 60 * 1)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + @extend_schema(tags=["summary"]) + @method_decorator(cache_page(60 * 60)) + def list(self, request, *args, **kwargs): + return super().list(request, *args, **kwargs) class TestsSummaryViewSet(ListModelMixin, GenericViewSet): @@ -107,9 +110,10 @@ class TestsSummaryViewSet(ListModelMixin, GenericViewSet): # return queryset.filter(facility__state=user.state) # return queryset.filter(facility__users__id__exact=user.id) + @extend_schema(tags=["summary"]) @method_decorator(cache_page(60 * 60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def list(self, request, *args, **kwargs): + return super().list(request, *args, **kwargs) class PatientSummaryViewSet(ListModelMixin, GenericViewSet): @@ -123,9 +127,10 @@ class PatientSummaryViewSet(ListModelMixin, GenericViewSet): filter_backends = (filters.DjangoFilterBackend,) filterset_class = FacilitySummaryFilter + @extend_schema(tags=["summary"]) @method_decorator(cache_page(60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def list(self, request, *args, **kwargs): + return super().list(request, *args, **kwargs) # def get_queryset(self): # user = self.request.user @@ -159,9 +164,10 @@ class DistrictPatientSummaryViewSet(ListModelMixin, GenericViewSet): filter_backends = (filters.DjangoFilterBackend,) filterset_class = DistrictSummaryFilter + @extend_schema(tags=["summary"]) @method_decorator(cache_page(60 * 10)) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def list(self, request, *args, **kwargs): + return super().list(request, *args, **kwargs) # def get_queryset(self): # user = self.request.user diff --git a/care/users/api/viewsets/change_password.py b/care/users/api/viewsets/change_password.py index b4b120de82..806eb0a414 100644 --- a/care/users/api/viewsets/change_password.py +++ b/care/users/api/viewsets/change_password.py @@ -1,4 +1,5 @@ from django.contrib.auth import get_user_model +from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import serializers, status from rest_framework.generics import UpdateAPIView from rest_framework.permissions import IsAuthenticated @@ -8,15 +9,18 @@ class ChangePasswordSerializer(serializers.Serializer): - model = User - """ Serializer for password change endpoint. """ + old_password = serializers.CharField(required=True) new_password = serializers.CharField(required=True) +@extend_schema_view( + put=extend_schema(tags=["users"]), + patch=extend_schema(tags=["users"]), +) class ChangePasswordView(UpdateAPIView): """ An endpoint for changing password. diff --git a/care/users/api/viewsets/lsg.py b/care/users/api/viewsets/lsg.py index ca1824ecb0..2b45ccbb35 100644 --- a/care/users/api/viewsets/lsg.py +++ b/care/users/api/viewsets/lsg.py @@ -1,6 +1,7 @@ from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from django_filters import rest_framework as filters +from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import mixins from rest_framework.decorators import action from rest_framework.pagination import PageNumberPagination @@ -21,6 +22,10 @@ class PaginataionOverrideClass(PageNumberPagination): page_size = 500 +@extend_schema_view( + list=extend_schema(tags=["places"]), + retrieve=extend_schema(tags=["places"]), +) class StateViewSet( ListCacheResponseMixin, RetrieveCacheResponseMixin, @@ -32,6 +37,7 @@ class StateViewSet( queryset = State.objects.all().order_by("id") pagination_class = PaginataionOverrideClass + @extend_schema(tags=["places"]) @method_decorator(cache_page(3600)) @action(detail=True, methods=["get"]) def districts(self, *args, **kwargs): @@ -48,6 +54,10 @@ class DistrictFilterSet(filters.FilterSet): district_name = filters.CharFilter(field_name="name", lookup_expr="icontains") +@extend_schema_view( + list=extend_schema(tags=["places"]), + retrieve=extend_schema(tags=["places"]), +) class DistrictViewSet( ListCacheResponseMixin, RetrieveCacheResponseMixin, @@ -61,6 +71,7 @@ class DistrictViewSet( filterset_class = DistrictFilterSet pagination_class = PaginataionOverrideClass + @extend_schema(tags=["places"]) @method_decorator(cache_page(3600)) @action(detail=True, methods=["get"]) def local_bodies(self, *args, **kwargs): @@ -70,6 +81,7 @@ def local_bodies(self, *args, **kwargs): ) return Response(data=serializer.data) + @extend_schema(tags=["places"]) @method_decorator(cache_page(3600)) @action(detail=True, methods=["get"]) def get_all_local_body(self, *args, **kwargs): @@ -96,6 +108,10 @@ class LocalBodyFilterSet(filters.FilterSet): local_body_name = filters.CharFilter(field_name="name", lookup_expr="icontains") +@extend_schema_view( + list=extend_schema(tags=["places"]), + retrieve=extend_schema(tags=["places"]), +) class LocalBodyViewSet( ListCacheResponseMixin, RetrieveCacheResponseMixin, @@ -126,6 +142,10 @@ class WardFilterSet(filters.FilterSet): ward_name = filters.CharFilter(field_name="name", lookup_expr="icontains") +@extend_schema_view( + list=extend_schema(tags=["places"]), + retrieve=extend_schema(tags=["places"]), +) class WardViewSet( ListCacheResponseMixin, RetrieveCacheResponseMixin, diff --git a/care/users/api/viewsets/users.py b/care/users/api/viewsets/users.py index ec35bf1d00..bd0faa6ecb 100644 --- a/care/users/api/viewsets/users.py +++ b/care/users/api/viewsets/users.py @@ -7,7 +7,6 @@ from rest_framework import filters as drf_filters from rest_framework import filters as rest_framework_filters from rest_framework import mixins, status -from rest_framework.authtoken.models import Token from rest_framework.decorators import action from rest_framework.generics import get_object_or_404 from rest_framework.permissions import IsAuthenticated @@ -130,6 +129,7 @@ def get_serializer_class(self): else: return UserSerializer + @extend_schema(tags=["users"]) @action(detail=False, methods=["GET"]) def getcurrentuser(self, request): return Response( @@ -137,20 +137,6 @@ def getcurrentuser(self, request): data=UserSerializer(request.user, context={"request": request}).data, ) - @action(detail=False, methods=["GET"]) - def get_token(self, request): - if not request.user.is_authenticated: - raise PermissionError - token, _ = Token.objects.get_or_create(user=request.user) - return Response(status=status.HTTP_200_OK, data={"token": token.key}) - - @action(detail=False, methods=["GET"]) - def delete_token(self, request): - if not request.user.is_authenticated: - raise PermissionError - Token.objects.filter(user=request.user).delete() - return Response(status=status.HTTP_204_NO_CONTENT) - def destroy(self, request, *args, **kwargs): queryset = self.queryset username = kwargs["username"] @@ -171,6 +157,7 @@ def destroy(self, request, *args, **kwargs): user.save(update_fields=["is_active"]) return Response(status=status.HTTP_204_NO_CONTENT) + @extend_schema(tags=["users"]) @action(detail=False, methods=["POST"]) def add_user(self, request, *args, **kwargs): password = request.data.pop( @@ -208,6 +195,7 @@ def has_user_type_permission_elevation(self, init_user, dest_user): def check_facility_user_exists(self, user, facility): return FacilityUser.objects.filter(facility=facility, user=user).exists() + @extend_schema(tags=["users"]) @action(detail=True, methods=["GET"], permission_classes=[IsAuthenticated]) def get_facilities(self, request, *args, **kwargs): user = self.get_object() @@ -217,6 +205,7 @@ def get_facilities(self, request, *args, **kwargs): facilities = FacilityBasicInfoSerializer(facilities, many=True) return Response(facilities.data) + @extend_schema(tags=["users"]) @action(detail=True, methods=["PUT"], permission_classes=[IsAuthenticated]) def add_facility(self, request, *args, **kwargs): # Remove User Facility Cache @@ -240,6 +229,7 @@ def add_facility(self, request, *args, **kwargs): FacilityUser(facility=facility, user=user, created_by=requesting_user).save() return Response(status=status.HTTP_201_CREATED) + @extend_schema(tags=["users"]) @extend_schema( request=None, responses={204: "Deleted Successfully"}, @@ -264,6 +254,7 @@ def clear_home_facility(self, request, *args, **kwargs): user.save(update_fields=["home_facility"]) return Response(status=status.HTTP_204_NO_CONTENT) + @extend_schema(tags=["users"]) @action(detail=True, methods=["DELETE"], permission_classes=[IsAuthenticated]) def delete_facility(self, request, *args, **kwargs): # Remove User Facility Cache @@ -289,6 +280,7 @@ def delete_facility(self, request, *args, **kwargs): FacilityUser.objects.filter(facility=facility, user=user).delete() return Response(status=status.HTTP_204_NO_CONTENT) + @extend_schema(tags=["users"]) @action( detail=True, methods=["PATCH", "GET"], @@ -311,6 +303,7 @@ def pnconfig(self, request, *args, **kwargs): user.save() return Response(status=status.HTTP_200_OK) + @extend_schema(tags=["users"]) @action(methods=["GET"], detail=True) def check_availability(self, request, username): """ diff --git a/care/users/reset_password_views.py b/care/users/reset_password_views.py index fc57cd781c..6cec930e4c 100644 --- a/care/users/reset_password_views.py +++ b/care/users/reset_password_views.py @@ -21,6 +21,7 @@ pre_password_reset, reset_password_token_created, ) +from drf_spectacular.utils import extend_schema from rest_framework import exceptions, serializers, status from rest_framework.generics import GenericAPIView from rest_framework.response import Response @@ -48,6 +49,7 @@ class ResetPasswordCheck(GenericAPIView): permission_classes = () + @extend_schema(tags=["auth", "users"]) def post(self, request, *args, **kwargs): token = request.data.get("token", None) @@ -93,6 +95,7 @@ class ResetPasswordConfirm(GenericAPIView): permission_classes = () serializer_class = PasswordTokenSerializer + @extend_schema(tags=["auth", "users"]) def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) @@ -171,6 +174,7 @@ class ResetPasswordRequestToken(GenericAPIView): permission_classes = () serializer_class = ResetPasswordUserSerializer + @extend_schema(tags=["auth", "users"]) def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) diff --git a/config/auth_views.py b/config/auth_views.py index ef2da9cbf2..36412d618d 100644 --- a/config/auth_views.py +++ b/config/auth_views.py @@ -1,12 +1,13 @@ from django.contrib.auth import authenticate, get_user_model from django.utils.timezone import localtime, now from django.utils.translation import gettext_lazy as _ +from drf_spectacular.utils import extend_schema from rest_framework import serializers, status from rest_framework_simplejwt.exceptions import AuthenticationFailed from rest_framework_simplejwt.serializers import PasswordField from rest_framework_simplejwt.settings import api_settings from rest_framework_simplejwt.tokens import RefreshToken -from rest_framework_simplejwt.views import TokenViewBase +from rest_framework_simplejwt.views import TokenVerifyView, TokenViewBase from config.ratelimit import ratelimit @@ -29,7 +30,7 @@ class TokenObtainSerializer(serializers.Serializer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields[self.username_field] = serializers.CharField() + self.fields[self.username_field] = serializers.CharField(write_only=True) self.fields["password"] = PasswordField() def validate(self, attrs): @@ -78,6 +79,7 @@ def get_token(cls, user): class TokenRefreshSerializer(serializers.Serializer): + access = serializers.CharField(read_only=True) refresh = serializers.CharField() def validate(self, attrs): @@ -109,6 +111,9 @@ def validate(self, attrs): class TokenObtainPairSerializer(TokenObtainSerializer): + refresh = serializers.CharField(read_only=True) + access = serializers.CharField(read_only=True) + @classmethod def get_token(cls, user): return RefreshToken.for_user(user) @@ -127,17 +132,42 @@ def validate(self, attrs): class TokenObtainPairView(TokenViewBase): """ + Generate access and refresh tokens for a user. + Takes a set of user credentials and returns an access and refresh JSON web token pair to prove the authentication of those credentials. """ serializer_class = TokenObtainPairSerializer + @extend_schema(tags=["auth"]) + def post(self, request, *args, **kwargs): + return super().post(request, *args, **kwargs) + class TokenRefreshView(TokenViewBase): """ + Refresh access token. + Takes a refresh type JSON web token and returns an access type JSON web token if the refresh token is valid. """ serializer_class = TokenRefreshSerializer + + @extend_schema(tags=["auth"]) + def post(self, request, *args, **kwargs): + return super().post(request, *args, **kwargs) + + +class AnnotatedTokenVerifyView(TokenVerifyView): + """ + Verify tokens are valid. + + Takes a token and returns a boolean of whether it is a valid JSON web token + for this project. + """ + + @extend_schema(tags=["auth"]) + def post(self, request, *args, **kwargs): + return super().post(request, *args, **kwargs) diff --git a/config/authentication.py b/config/authentication.py index 86edff3cc1..0577dfa6b1 100644 --- a/config/authentication.py +++ b/config/authentication.py @@ -4,6 +4,8 @@ import requests from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ +from drf_spectacular.extensions import OpenApiAuthenticationExtension +from drf_spectacular.plumbing import build_bearer_security_scheme_object from rest_framework import HTTP_HEADER_ENCODING from rest_framework.authentication import BasicAuthentication from rest_framework_simplejwt.authentication import JWTAuthentication @@ -152,3 +154,58 @@ def get_user(self, validated_token, facility): ) asset_user.save() return asset_user + + +class CustomJWTAuthenticationScheme(OpenApiAuthenticationExtension): + target_class = "config.authentication.CustomJWTAuthentication" + name = "jwtAuth" + + def get_security_definition(self, auto_schema): + return build_bearer_security_scheme_object( + header_name="Authorization", token_prefix="Bearer", bearer_format="JWT" + ) + + +class MiddlewareAuthenticationScheme(OpenApiAuthenticationExtension): + target_class = "config.authentication.MiddlewareAuthentication" + name = "middlewareAuth" + + def get_security_definition(self, auto_schema): + return { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": _( + "Used for authenticating requests from the middleware. " + "The scheme requires a valid JWT token in the Authorization header " + "along with the facility id in the X-Facility-Id header. " + "--The value field is just for preview, filling it will show allowed " + "endpoints.--" + ), + } + + +class CustomBasicAuthenticationScheme(OpenApiAuthenticationExtension): + target_class = "config.authentication.CustomBasicAuthentication" + name = "basicAuth" + + def get_security_definition(self, auto_schema): + return { + "type": "http", + "scheme": "basic", + "description": _("Do not use this scheme for production."), + } + + +class SessionAuthenticationScheme(OpenApiAuthenticationExtension): + target_class = "rest_framework.authentication.SessionAuthentication" + name = "cookieAuth" + + def get_security_definition(self, auto_schema): + return { + "type": "apiKey", + "in": "cookie", + "name": "sessionid", + "scheme": "http", + "description": _("Do not use this scheme for production."), + } diff --git a/config/settings/base.py b/config/settings/base.py index 23cc0f98ab..be25ee389e 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -316,13 +316,12 @@ # https://www.django-rest-framework.org/api-guide/settings/ REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( - "rest_framework.authentication.BasicAuthentication", + # "rest_framework.authentication.BasicAuthentication", # Primary api authentication # "rest_framework_simplejwt.authentication.JWTAuthentication", "config.authentication.CustomJWTAuthentication", "config.authentication.CustomBasicAuthentication", "rest_framework.authentication.SessionAuthentication", - "rest_framework.authentication.TokenAuthentication", ), "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", "PAGE_SIZE": 14, diff --git a/config/urls.py b/config/urls.py index cb9d85d5d6..ab1c88fbdc 100644 --- a/config/urls.py +++ b/config/urls.py @@ -8,7 +8,6 @@ SpectacularRedocView, SpectacularSwaggerView, ) -from rest_framework_simplejwt.views import TokenVerifyView from care.facility.api.viewsets.open_id import OpenIdConfigView from care.hcx.api.viewsets.listener import ( @@ -25,7 +24,7 @@ from config import api_router from config.health_views import MiddlewareAuthenticationVerifyView -from .auth_views import TokenObtainPairView, TokenRefreshView +from .auth_views import AnnotatedTokenVerifyView, TokenObtainPairView, TokenRefreshView from .views import home_view urlpatterns = [ @@ -37,7 +36,11 @@ path( "api/v1/auth/token/refresh/", TokenRefreshView.as_view(), name="token_refresh" ), - path("api/v1/auth/token/verify/", TokenVerifyView.as_view(), name="token_verify"), + path( + "api/v1/auth/token/verify/", + AnnotatedTokenVerifyView.as_view(), + name="token_verify", + ), path( "api/v1/password_reset/", ResetPasswordRequestToken.as_view(), From 73a504a6cc401d420116114da973d003971fd656 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Sat, 17 Jun 2023 12:55:49 +0530 Subject: [PATCH 19/24] update migrations --- .../migrations/0362_merge_20230617_1253.py | 12 +++++ care/hcx/api/viewsets/gateway.py | 2 +- care/hcx/api/viewsets/listener.py | 2 +- .../migrations/0008_merge_20230617_1253.py | 12 +++++ ...nication_content_alter_communication_id.py | 48 +++++++++++++++++++ care/hcx/models/communication.py | 3 +- 6 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 care/facility/migrations/0362_merge_20230617_1253.py create mode 100644 care/hcx/migrations/0008_merge_20230617_1253.py create mode 100644 care/hcx/migrations/0009_alter_communication_content_alter_communication_id.py diff --git a/care/facility/migrations/0362_merge_20230617_1253.py b/care/facility/migrations/0362_merge_20230617_1253.py new file mode 100644 index 0000000000..c358c195ed --- /dev/null +++ b/care/facility/migrations/0362_merge_20230617_1253.py @@ -0,0 +1,12 @@ +# Generated by Django 4.2.2 on 2023-06-17 07:23 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0004_alter_historicalfacilitycapacity_options_and_more"), + ("facility", "0361_merge_20230610_2126"), + ] + + operations = [] diff --git a/care/hcx/api/viewsets/gateway.py b/care/hcx/api/viewsets/gateway.py index 4bc2338c25..998d6da059 100644 --- a/care/hcx/api/viewsets/gateway.py +++ b/care/hcx/api/viewsets/gateway.py @@ -263,7 +263,7 @@ def make_claim(self, request): return Response(dict(response.get("response")), status=status.HTTP_200_OK) - @swagger_auto_schema(tags=["hcx"], request_body=SendCommunicationSerializer()) + @extend_schema(tags=["hcx"], request=SendCommunicationSerializer()) @action(detail=False, methods=["post"]) def send_communication(self, request): data = request.data diff --git a/care/hcx/api/viewsets/listener.py b/care/hcx/api/viewsets/listener.py index ae4bf02a68..fd2f6922e3 100644 --- a/care/hcx/api/viewsets/listener.py +++ b/care/hcx/api/viewsets/listener.py @@ -98,7 +98,7 @@ class CommunicationRequestView(GenericAPIView): permission_classes = (AllowAny,) authentication_classes = [] - @swagger_auto_schema(tags=["hcx"]) + @extend_schema(tags=["hcx"]) def post(self, request, *args, **kwargs): response = Hcx().processIncomingRequest(request.data["payload"]) data = Fhir().process_communication_request(response["payload"]) diff --git a/care/hcx/migrations/0008_merge_20230617_1253.py b/care/hcx/migrations/0008_merge_20230617_1253.py new file mode 100644 index 0000000000..587f806bca --- /dev/null +++ b/care/hcx/migrations/0008_merge_20230617_1253.py @@ -0,0 +1,12 @@ +# Generated by Django 4.2.2 on 2023-06-17 07:23 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("hcx", "0002_alter_claim_id_alter_claim_items_alter_policy_id"), + ("hcx", "0007_communication"), + ] + + operations = [] diff --git a/care/hcx/migrations/0009_alter_communication_content_alter_communication_id.py b/care/hcx/migrations/0009_alter_communication_content_alter_communication_id.py new file mode 100644 index 0000000000..0a43c19cf4 --- /dev/null +++ b/care/hcx/migrations/0009_alter_communication_content_alter_communication_id.py @@ -0,0 +1,48 @@ +# Generated by Django 4.2.2 on 2023-06-17 07:23 + +from django.db import migrations, models + +import care.utils.models.validators + + +class Migration(migrations.Migration): + dependencies = [ + ("hcx", "0008_merge_20230617_1253"), + ] + + operations = [ + migrations.AlterField( + model_name="communication", + name="content", + field=models.JSONField( + default=list, + null=True, + validators=[ + care.utils.models.validators.JSONFieldSchemaValidator( + { + "$schema": "http://json-schema.org/draft-07/schema#", + "content": [ + { + "additionalProperties": False, + "properties": { + "data": {"type": "string"}, + "type": {"type": "string"}, + }, + "required": ["type", "data"], + "type": "object", + } + ], + "type": "array", + } + ) + ], + ), + ), + migrations.AlterField( + model_name="communication", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ] diff --git a/care/hcx/models/communication.py b/care/hcx/models/communication.py index 18c8cf43d5..c0a8b2e6f2 100644 --- a/care/hcx/models/communication.py +++ b/care/hcx/models/communication.py @@ -1,4 +1,3 @@ -from django.contrib.postgres.fields import JSONField from django.db import models from care.hcx.models.claim import Claim @@ -12,7 +11,7 @@ class Communication(BaseModel): identifier = models.TextField(null=True, blank=True) claim = models.ForeignKey(Claim, on_delete=models.CASCADE) - content = JSONField( + content = models.JSONField( default=list, validators=[JSONFieldSchemaValidator(CONTENT)], null=True ) From 2c73695e87c3f262161ab0b1b8fc68a187286cdf Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Sat, 17 Jun 2023 13:10:23 +0530 Subject: [PATCH 20/24] Revert "fix test cases" This reverts commit 147425786c1cfad2c4d788158192a2eda982bdae. --- care/facility/tests/test_facility_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/care/facility/tests/test_facility_api.py b/care/facility/tests/test_facility_api.py index a132186627..fc3a8c967c 100644 --- a/care/facility/tests/test_facility_api.py +++ b/care/facility/tests/test_facility_api.py @@ -56,7 +56,7 @@ def test_no_auth(self): {"get": "list"}, FacilityViewSet, ) - self.assertIs(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertIs(response.status_code, status.HTTP_403_FORBIDDEN) sample_data = {} create_response = self.new_request( @@ -64,4 +64,4 @@ def test_no_auth(self): {"post": "create"}, FacilityViewSet, ) - self.assertIs(create_response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertIs(create_response.status_code, status.HTTP_403_FORBIDDEN) From ede6933b2db09da0a2fb747d0dc1b1239e9b0400 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 19 Jun 2023 13:45:17 +0530 Subject: [PATCH 21/24] fix dummy serializers --- care/facility/api/serializers/ambulance.py | 13 ++++++++++++ care/facility/api/serializers/asset.py | 9 ++++++++ .../api/serializers/patient_consultation.py | 3 +++ .../api/serializers/patient_investigation.py | 3 +++ care/facility/api/viewsets/ambulance.py | 21 +++++++++---------- care/facility/api/viewsets/asset.py | 11 +++++----- care/facility/api/viewsets/notification.py | 16 +++++++------- 7 files changed, 52 insertions(+), 24 deletions(-) diff --git a/care/facility/api/serializers/ambulance.py b/care/facility/api/serializers/ambulance.py index 664ea11d1f..1668922158 100644 --- a/care/facility/api/serializers/ambulance.py +++ b/care/facility/api/serializers/ambulance.py @@ -57,3 +57,16 @@ def update(self, instance, validated_data): validated_data.pop("drivers", []) ambulance = super(AmbulanceSerializer, self).update(instance, validated_data) return ambulance + + +class DeleteDriverSerializer(serializers.Serializer): + driver_id = serializers.IntegerField() + + def update(self, instance, validated_data): + raise NotImplementedError + + def create(self, validated_data): + raise NotImplementedError + + class Meta: + fields = ("driver_id",) diff --git a/care/facility/api/serializers/asset.py b/care/facility/api/serializers/asset.py index c14e7c8751..fbb9f44970 100644 --- a/care/facility/api/serializers/asset.py +++ b/care/facility/api/serializers/asset.py @@ -191,11 +191,20 @@ def actionChoices(): ) data = JSONField(required=False) + class Meta: + fields = ("type", "data") + class DummyAssetOperateSerializer(Serializer): action = AssetActionSerializer(required=True) + class Meta: + fields = ("action",) + class DummyAssetOperateResponseSerializer(Serializer): message = CharField(required=True) result = JSONField(required=False) + + class Meta: + fields = ("message", "result") diff --git a/care/facility/api/serializers/patient_consultation.py b/care/facility/api/serializers/patient_consultation.py index be74cff48d..f20f60021f 100644 --- a/care/facility/api/serializers/patient_consultation.py +++ b/care/facility/api/serializers/patient_consultation.py @@ -480,3 +480,6 @@ def validate(self, attrs): if not attrs.get("email"): attrs["email"] = self.context["request"].user.email return attrs + + class Meta: + fields = ("email",) diff --git a/care/facility/api/serializers/patient_investigation.py b/care/facility/api/serializers/patient_investigation.py index aa97b42535..bc209b1e68 100644 --- a/care/facility/api/serializers/patient_investigation.py +++ b/care/facility/api/serializers/patient_investigation.py @@ -92,3 +92,6 @@ class Meta: # Dummy for Spec class InvestigationUpdateSerializer(serializers.Serializer): investigations = ValueSerializer(many=True) + + class Meta: + fields = ("investigations",) diff --git a/care/facility/api/viewsets/ambulance.py b/care/facility/api/viewsets/ambulance.py index 99ced76c6b..f67e3457a4 100644 --- a/care/facility/api/viewsets/ambulance.py +++ b/care/facility/api/viewsets/ambulance.py @@ -16,6 +16,7 @@ from care.facility.api.serializers.ambulance import ( AmbulanceDriverSerializer, AmbulanceSerializer, + DeleteDriverSerializer, ) from care.facility.api.viewsets import UserAccessMixin from care.facility.models.ambulance import Ambulance @@ -55,11 +56,18 @@ class AmbulanceViewSet( filter_backends = (filters.DjangoFilterBackend,) filterset_class = AmbulanceFilterSet + def get_serializer_class(self): + if self.action == "add_driver": + return AmbulanceDriverSerializer + elif self.action == "remove_driver": + return DeleteDriverSerializer + return AmbulanceSerializer + @extend_schema(tags=["ambulance"]) @action(methods=["POST"], detail=True) def add_driver(self, request): ambulance = self.get_object() - serializer = AmbulanceDriverSerializer(data=request.data) + serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) driver = ambulance.ambulancedriver_set.create(**serializer.validated_data) @@ -71,17 +79,8 @@ def add_driver(self, request): @extend_schema(tags=["ambulance"]) @action(methods=["DELETE"], detail=True) def remove_driver(self, request): - class DeleteDriverSerializer(serializers.Serializer): - driver_id = serializers.IntegerField() - - def update(self, instance, validated_data): - raise NotImplementedError - - def create(self, validated_data): - raise NotImplementedError - ambulance = self.get_object() - serializer = DeleteDriverSerializer(data=request.data) + serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) driver = ambulance.ambulancedriver_set.filter( diff --git a/care/facility/api/viewsets/asset.py b/care/facility/api/viewsets/asset.py index a156c1e464..57ec16da51 100644 --- a/care/facility/api/viewsets/asset.py +++ b/care/facility/api/viewsets/asset.py @@ -3,7 +3,7 @@ from django.http import Http404 from django.shortcuts import get_object_or_404 from django_filters import rest_framework as filters -from drf_spectacular.utils import extend_schema +from drf_spectacular.utils import extend_schema, inline_serializer from dry_rest_permissions.generics import DRYPermissions from rest_framework import exceptions from rest_framework import filters as drf_filters @@ -19,7 +19,7 @@ ) from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from rest_framework.serializers import Serializer, UUIDField +from rest_framework.serializers import UUIDField from rest_framework.viewsets import GenericViewSet from care.facility.api.serializers.asset import ( @@ -185,11 +185,10 @@ def get_default_user_location(self, request, *args, **kwargs): ) return Response(UserDefaultAssetLocationSerializer(obj).data) - class DummyAssetSerializer(Serializer): # Dummy for Spec - location = UUIDField(required=True) - @extend_schema( - request=DummyAssetSerializer, + request=inline_serializer( + "AssetLocationFieldSerializer", fields={"location": UUIDField()} + ), responses={200: UserDefaultAssetLocationSerializer()}, tags=["asset"], ) diff --git a/care/facility/api/viewsets/notification.py b/care/facility/api/viewsets/notification.py index 35d4a76e78..05f42ff6e0 100644 --- a/care/facility/api/viewsets/notification.py +++ b/care/facility/api/viewsets/notification.py @@ -1,6 +1,6 @@ from django.conf import settings from django_filters import rest_framework as filters -from drf_spectacular.utils import extend_schema +from drf_spectacular.utils import extend_schema, inline_serializer from rest_framework import status from rest_framework.decorators import action from rest_framework.exceptions import ValidationError @@ -8,7 +8,7 @@ from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, UpdateModelMixin from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly from rest_framework.response import Response -from rest_framework.serializers import CharField, Serializer, UUIDField +from rest_framework.serializers import CharField, UUIDField from rest_framework.viewsets import GenericViewSet from care.facility.api.serializers.notification import NotificationSerializer @@ -53,12 +53,14 @@ def get_queryset(self): def public_key(self, request, *args, **kwargs): return Response({"public_key": settings.VAPID_PUBLIC_KEY}) - class DummyNotificationSerializer(Serializer): # Dummy for Spec - facility = UUIDField(required=True) - message = CharField(required=True) - @extend_schema( - request=DummyNotificationSerializer, + request=inline_serializer( + "BoardMessageSerializer", + fields={ + "facility": UUIDField(required=True), + "message": CharField(required=True), + }, + ), responses={204: "Notification Processed"}, tags=["notification"], ) From df443ac3fc2dfe6dc8a19a0c2c62caf5c6a72c36 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Mon, 19 Jun 2023 16:23:37 +0530 Subject: [PATCH 22/24] limit PatientRegisteration fields for PatientSearch --- care/facility/api/serializers/patient.py | 18 ++++++++++-------- care/facility/api/viewsets/patient.py | 12 +++++++++++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 788bb2b8f4..e1fe82f098 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -411,16 +411,18 @@ class PatientSearchSerializer(serializers.ModelSerializer): gender = ChoiceField(choices=GENDER_CHOICES) patient_id = serializers.UUIDField(source="external_id", read_only=True) - # facility_id = serializers.UUIDField(read_only=True, allow_null=True) - class Meta: model = PatientRegistration - exclude = ( - "date_of_birth", - "year_of_birth", - "external_id", - "id", - ) + TIMESTAMP_FIELDS + fields = ( + "patient_id", + "name", + "gender", + "phone_number", + "state_id", + "facility", + "allow_transfer", + "is_active", + ) class PatientTransferSerializer(serializers.ModelSerializer): diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index e55fa3443e..8b88653e61 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -491,7 +491,17 @@ class PatientSearchSetPagination(PageNumberPagination): class PatientSearchViewSet(UserAccessMixin, ListModelMixin, GenericViewSet): http_method_names = ["get"] - queryset = PatientRegistration.objects.all() + queryset = PatientRegistration.objects.only( + "id", + "external_id", + "name", + "gender", + "phone_number", + "state_id", + "facility", + "allow_transfer", + "is_active", + ) serializer_class = PatientSearchSerializer permission_classes = (IsAuthenticated, DRYPermissions) pagination_class = PatientSearchSetPagination From 215f987071bcde98186817632d536333c14104c4 Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 20 Jun 2023 14:39:23 +0530 Subject: [PATCH 23/24] UserAccessMixin is not being used in PatientSearch --- care/facility/api/viewsets/patient.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index 8b88653e61..1cccd82598 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -32,7 +32,6 @@ PatientTransferSerializer, ) from care.facility.api.serializers.patient_icmr import PatientICMRSerializer -from care.facility.api.viewsets import UserAccessMixin from care.facility.api.viewsets.mixins.history import HistoryMixin from care.facility.models import ( CATEGORY_CHOICES, @@ -489,7 +488,7 @@ class PatientSearchSetPagination(PageNumberPagination): page_size = 200 -class PatientSearchViewSet(UserAccessMixin, ListModelMixin, GenericViewSet): +class PatientSearchViewSet(ListModelMixin, GenericViewSet): http_method_names = ["get"] queryset = PatientRegistration.objects.only( "id", From 494b4a71de61aa1015a0443f89b14dbe8e34420f Mon Sep 17 00:00:00 2001 From: Aakash Singh Date: Tue, 20 Jun 2023 14:40:23 +0530 Subject: [PATCH 24/24] update default mail addresses --- config/settings/base.py | 10 +++++++--- config/settings/deployment.py | 10 ---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index be25ee389e..3e922dc1c0 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -269,20 +269,24 @@ EMAIL_TIMEOUT = 5 # https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email DEFAULT_FROM_EMAIL = env( - "EMAIL_FROM", default="Open Healthcare Network " + "EMAIL_FROM", default="Open Healthcare Network " ) EMAIL_HOST = env("EMAIL_HOST", default="localhost") EMAIL_PORT = env("EMAIL_PORT", default=587) EMAIL_HOST_USER = env("EMAIL_USER", default="") EMAIL_HOST_PASSWORD = env("EMAIL_PASSWORD", default="") EMAIL_USE_TLS = env("EMAIL_USE_TLS", default=False) +# https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix +EMAIL_SUBJECT_PREFIX = env("DJANGO_EMAIL_SUBJECT_PREFIX", default="[Care]") # ADMIN # ------------------------------------------------------------------------------ +# https://docs.djangoproject.com/en/dev/ref/settings/#server-email +# SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) # noqa F405 # https://docs.djangoproject.com/en/dev/ref/settings/#admins -ADMINS = [("""👪""", "admin@ohc.network")] +# ADMINS = [("""👪""", "admin@ohc.network")] # https://docs.djangoproject.com/en/dev/ref/settings/#managers -MANAGERS = ADMINS +# MANAGERS = ADMINS # Django Admin URL. ADMIN_URL = env("DJANGO_ADMIN_URL", default="admin/") diff --git a/config/settings/deployment.py b/config/settings/deployment.py index 63e1b2ccdc..7c43be9685 100644 --- a/config/settings/deployment.py +++ b/config/settings/deployment.py @@ -9,10 +9,6 @@ from .base import * # noqa from .base import env -# GENERAL -# ------------------------------------------------------------------------------ - - # DATABASES # ------------------------------------------------------------------------------ DATABASES["default"] = env.db("DATABASE_URL", default=env("POSTGIS_URL")) # noqa F405 @@ -61,12 +57,6 @@ # ------------------------------------------------------------------------------ EMAIL_USE_TLS = True - -# https://docs.djangoproject.com/en/dev/ref/settings/#server-email -SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) # noqa F405 -# https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix -EMAIL_SUBJECT_PREFIX = env("DJANGO_EMAIL_SUBJECT_PREFIX", default="[Care]") - # Anymail # ------------------------------------------------------------------------------ # https://anymail.readthedocs.io/en/stable/installation/#installing-anymail