diff --git a/care/emr/api/viewsets/encounter.py b/care/emr/api/viewsets/encounter.py index d81769e96d..990114e192 100644 --- a/care/emr/api/viewsets/encounter.py +++ b/care/emr/api/viewsets/encounter.py @@ -27,6 +27,7 @@ Patient, ) from care.emr.models.patient import PatientIdentifier, PatientIdentifierConfig +from care.emr.resources.base import model_from_cache from care.emr.resources.encounter.constants import COMPLETED_CHOICES, StatusChoices from care.emr.resources.encounter.spec import ( EncounterCareTeamMemberWriteSpec, @@ -263,9 +264,9 @@ def organizations(self, request, *args, **kwargs): encounter=instance ).select_related("organization") data = [ - FacilityOrganizationReadSpec.serialize( - encounter_organization.organization - ).to_json() + model_from_cache( + FacilityOrganizationReadSpec, id=encounter_organization.organization.id + ) for encounter_organization in encounter_organizations ] return Response({"results": data}) @@ -295,7 +296,9 @@ def organizations_add(self, request, *args, **kwargs): EncounterOrganization.objects.create( encounter=instance, organization=organization ) - return Response(FacilityOrganizationReadSpec.serialize(organization).to_json()) + return Response( + model_from_cache(FacilityOrganizationReadSpec, id=organization.id) + ) @extend_schema( request=EncounterOrganizationManageSpec, diff --git a/care/emr/api/viewsets/location.py b/care/emr/api/viewsets/location.py index f83c67775b..7a39ef6058 100644 --- a/care/emr/api/viewsets/location.py +++ b/care/emr/api/viewsets/location.py @@ -16,6 +16,7 @@ FacilityLocationOrganization, ) from care.emr.models.organization import FacilityOrganization, FacilityOrganizationUser +from care.emr.resources.base import model_from_cache from care.emr.resources.encounter.constants import COMPLETED_CHOICES from care.emr.resources.facility_organization.spec import FacilityOrganizationReadSpec from care.emr.resources.location.spec import ( @@ -180,9 +181,9 @@ def organizations(self, request, *args, **kwargs): location=instance ).select_related("organization") data = [ - FacilityOrganizationReadSpec.serialize( - encounter_organization.organization - ).to_json() + model_from_cache( + FacilityOrganizationReadSpec, id=encounter_organization.organization.id + ) for encounter_organization in encounter_organizations ] return Response({"results": data}) @@ -219,7 +220,9 @@ def organizations_add(self, request, *args, **kwargs): FacilityLocationOrganization.objects.create( location=instance, organization=organization ) - return Response(FacilityOrganizationReadSpec.serialize(organization).to_json()) + return Response( + model_from_cache(FacilityOrganizationReadSpec, id=organization.id) + ) @extend_schema( request=FacilityLocationOrganizationManageSpec, responses={200: None} diff --git a/care/emr/api/viewsets/patient.py b/care/emr/api/viewsets/patient.py index 43bfbb0d3a..0ae587268d 100644 --- a/care/emr/api/viewsets/patient.py +++ b/care/emr/api/viewsets/patient.py @@ -15,6 +15,7 @@ from care.emr.models import Organization, PatientUser, TokenBooking from care.emr.models.patient import Patient, PatientIdentifier, PatientIdentifierConfig from care.emr.models.scheduling.token import Token +from care.emr.resources.base import model_from_cache from care.emr.resources.patient.spec import ( PatientCreateSpec, PatientIdentifierConfigRequest, @@ -285,7 +286,7 @@ def get_users(self, request, *args, **kwargs): patient = self.get_object() patient_users = PatientUser.objects.filter(patient=patient) data = [ - UserSpec.serialize(patient_user.user).to_json() + model_from_cache(UserSpec, id=patient_user.user_id) for patient_user in patient_users ] return Response({"results": data}) @@ -305,7 +306,7 @@ def add_user(self, request, *args, **kwargs): if PatientUser.objects.filter(user=user, patient=patient).exists(): raise ValidationError("User already exists") PatientUser.objects.create(user=user, patient=patient, role=role) - return Response(UserSpec.serialize(user).to_json()) + return Response(model_from_cache(UserSpec, id=user.id)) class PatientUserDeleteSpec(BaseModel): user: UUID4 diff --git a/care/emr/api/viewsets/questionnaire.py b/care/emr/api/viewsets/questionnaire.py index 1eb31e8f46..1fce41ed22 100644 --- a/care/emr/api/viewsets/questionnaire.py +++ b/care/emr/api/viewsets/questionnaire.py @@ -17,6 +17,7 @@ QuestionnaireTag, ) from care.emr.models.questionnaire import FormSubmission, QuestionnaireResponse +from care.emr.resources.base import model_from_cache from care.emr.resources.favorites.filters import FavoritesFilter from care.emr.resources.favorites.spec import FavoriteResourceChoices from care.emr.resources.form_submission.spec import FormSubmissionStatusChoices @@ -193,10 +194,10 @@ def get_organizations(self, request, *args, **kwargs): questionnaire = self.get_object() questionnaire_organizations = QuestionnaireOrganization.objects.filter( questionnaire=questionnaire - ).select_related("organization") + ).values_list("organization_id", flat=True) organizations_serialized = [ - OrganizationReadSpec.serialize(obj.organization).to_json() - for obj in questionnaire_organizations + model_from_cache(OrganizationReadSpec, id=org_id) + for org_id in questionnaire_organizations ] return Response( { @@ -254,10 +255,10 @@ def set_organizations(self, request, *args, **kwargs): questionnaire=questionnaire, organization=organization ) organizations_serialized = [ - OrganizationReadSpec.serialize(obj.organization).to_json() - for obj in QuestionnaireOrganization.objects.filter( + model_from_cache(OrganizationReadSpec, id=org_id) + for org_id in QuestionnaireOrganization.objects.filter( questionnaire=questionnaire - ).select_related("organization") + ).values_list("organization_id", flat=True) ] return Response( { diff --git a/care/emr/api/viewsets/scheduling/booking.py b/care/emr/api/viewsets/scheduling/booking.py index 232fc52345..a3bbca11f0 100644 --- a/care/emr/api/viewsets/scheduling/booking.py +++ b/care/emr/api/viewsets/scheduling/booking.py @@ -29,6 +29,7 @@ ) from care.emr.models.scheduling import SchedulableResource, TokenBooking from care.emr.models.scheduling.token import Token, TokenCategory, TokenQueue +from care.emr.resources.base import model_from_cache from care.emr.resources.charge_item.handle_charge_item_cancel import ( handle_charge_item_cancel, ) @@ -277,7 +278,7 @@ def available_users(self, request, *args, **kwargs): return Response( { "users": [ - UserSpec.serialize(user_resource.user).to_json() + model_from_cache(UserSpec, id=user_resource.user_id) for user_resource in user_resources ] } diff --git a/care/emr/resources/allergy_intolerance/spec.py b/care/emr/resources/allergy_intolerance/spec.py index b56dffa37e..fee0e4eb58 100644 --- a/care/emr/resources/allergy_intolerance/spec.py +++ b/care/emr/resources/allergy_intolerance/spec.py @@ -8,7 +8,6 @@ from care.emr.resources.allergy_intolerance.valueset import CARE_ALLERGY_CODE_VALUESET from care.emr.resources.base import EMRResource from care.emr.resources.common.coding import Coding -from care.emr.resources.user.spec import UserSpec from care.emr.utils.valueset_coding_type import ValueSetBoundCoding @@ -134,9 +133,6 @@ class AllergyIntoleranceReadSpec(BaseAllergyIntoleranceSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) if obj.encounter: mapping["encounter"] = obj.encounter.external_id diff --git a/care/emr/resources/base.py b/care/emr/resources/base.py index c05e743f74..37c5cf9583 100644 --- a/care/emr/resources/base.py +++ b/care/emr/resources/base.py @@ -162,9 +162,9 @@ def to_json(self): def serialize_audit_users(cls, mapping, obj): from care.emr.resources.user.spec import UserSpec - if obj.created_by_id: + if hasattr(obj, "created_by_id") and obj.created_by_id: mapping["created_by"] = model_from_cache(UserSpec, id=obj.created_by_id) - if obj.updated_by_id: + if hasattr(obj, "updated_by_id") and obj.updated_by_id: mapping["updated_by"] = model_from_cache(UserSpec, id=obj.updated_by_id) @@ -272,7 +272,7 @@ def model_from_cache(model: EMRResource, quiet=True, **kwargs) -> dict[str, Any] data = model.serialize(obj) cache.set(model_cache_key(model_string(db_model), model.__name__, pk), data) - return dict(data) + return data.model_dump(mode="json") # TODO: add param for manually adding dependencies for cache invalidation diff --git a/care/emr/resources/condition/spec.py b/care/emr/resources/condition/spec.py index 94a3e55ffe..460d7fee56 100644 --- a/care/emr/resources/condition/spec.py +++ b/care/emr/resources/condition/spec.py @@ -131,10 +131,7 @@ def perform_extra_serialization(cls, mapping, obj): if obj.encounter: mapping["encounter"] = obj.encounter.external_id - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) class ConditionUpdateSpec(BaseConditionSpec): diff --git a/care/emr/resources/consent/spec.py b/care/emr/resources/consent/spec.py index 00018603b0..5784bdf160 100644 --- a/care/emr/resources/consent/spec.py +++ b/care/emr/resources/consent/spec.py @@ -7,7 +7,7 @@ from care.emr.models import Encounter, FileUpload from care.emr.models.consent import Consent -from care.emr.resources.base import EMRResource, PeriodSpec +from care.emr.resources.base import EMRResource, PeriodSpec, model_from_cache from care.emr.resources.file_upload.spec import ( FileCategoryChoices, FileTypeChoices, @@ -117,9 +117,9 @@ def perform_extra_serialization(cls, mapping, obj): mapping["encounter"] = obj.encounter.external_id for verification in obj.verification_details: - verification["verified_by"] = UserSpec.serialize( - User.objects.get(external_id=verification["verified_by"]) - ).to_json() + verification["verified_by"] = model_from_cache( + UserSpec, external_id=verification["verified_by"] + ) mapping["verification_details"] = obj.verification_details diff --git a/care/emr/resources/device/history_spec.py b/care/emr/resources/device/history_spec.py index 35dda7b4f9..2e8e3b5e0c 100644 --- a/care/emr/resources/device/history_spec.py +++ b/care/emr/resources/device/history_spec.py @@ -3,9 +3,8 @@ from pydantic import UUID4 from care.emr.models import DeviceServiceHistory -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.user.spec import UserSpec -from care.users.models import User class DeviceServiceHistorySpecBase(EMRResource): @@ -41,10 +40,9 @@ def perform_extra_serialization(cls, mapping, obj): edit_history = [] for history in obj.edit_history: user = history.get("updated_by") - user_obj = User.objects.filter(id=user).first() - if user_obj: - history["updated_by"] = UserSpec.serialize(user_obj).to_json() + if user: + history["updated_by"] = model_from_cache(UserSpec, id=user) else: - history["updated_by"] = {} # Edge Case + history["updated_by"] = {} edit_history.append(history) mapping["edit_history"] = edit_history diff --git a/care/emr/resources/device/spec.py b/care/emr/resources/device/spec.py index 3f9bce4c13..88d4c2bf4c 100644 --- a/care/emr/resources/device/spec.py +++ b/care/emr/resources/device/spec.py @@ -5,7 +5,7 @@ from care.emr.models import Device, DeviceEncounterHistory, DeviceLocationHistory from care.emr.registries.device_type.device_registry import DeviceTypeRegistry -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.common.contact_point import ContactPoint from care.emr.resources.encounter.spec import EncounterListSpec from care.emr.resources.facility_organization.spec import FacilityOrganizationReadSpec @@ -110,9 +110,9 @@ def perform_extra_serialization(cls, mapping, obj): mapping["care_metadata"] = care_device_class().retrieve(obj) if obj.managing_organization: - mapping["managing_organization"] = FacilityOrganizationReadSpec.serialize( - obj.managing_organization - ).to_json() + mapping["managing_organization"] = model_from_cache( + FacilityOrganizationReadSpec, id=obj.managing_organization.id + ) class DeviceLocationHistoryListSpec(EMRResource): diff --git a/care/emr/resources/encounter/spec.py b/care/emr/resources/encounter/spec.py index 4ea072e906..cd97578103 100644 --- a/care/emr/resources/encounter/spec.py +++ b/care/emr/resources/encounter/spec.py @@ -163,7 +163,9 @@ def perform_extra_serialization(cls, mapping, obj): ).to_json() organizations = EncounterOrganization.objects.filter(encounter=obj) mapping["organizations"] = [ - FacilityOrganizationReadSpec.serialize(encounter_org.organization).to_json() + model_from_cache( + FacilityOrganizationReadSpec, id=encounter_org.organization.id + ) for encounter_org in organizations ] mapping["location_history"] = [ diff --git a/care/emr/resources/facility/spec.py b/care/emr/resources/facility/spec.py index 5cb0db567c..e2372644d4 100644 --- a/care/emr/resources/facility/spec.py +++ b/care/emr/resources/facility/spec.py @@ -105,17 +105,14 @@ class FacilityReadSpec(FacilityBaseSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): - from care.emr.resources.user.spec import UserSpec - mapping["id"] = obj.external_id mapping["read_cover_image_url"] = obj.read_cover_image_url() - if obj.created_by: - mapping["created_by"] = model_from_cache(UserSpec, id=obj.created_by_id) + cls.serialize_audit_users(mapping, obj) mapping["facility_type"] = REVERSE_FACILITY_TYPES[obj.facility_type] if obj.geo_organization: - mapping["geo_organization"] = OrganizationReadSpec.serialize( - obj.geo_organization - ).to_json() + mapping["geo_organization"] = model_from_cache( + OrganizationReadSpec, id=obj.geo_organization.id + ) class FacilityRetrieveSpec(FacilityReadSpec, FacilityPermissionsMixin): @@ -215,6 +212,6 @@ def perform_extra_serialization(cls, mapping, obj): mapping["read_cover_image_url"] = obj.read_cover_image_url() mapping["facility_type"] = REVERSE_FACILITY_TYPES[obj.facility_type] if obj.geo_organization: - mapping["geo_organization"] = OrganizationReadSpec.serialize( - obj.geo_organization - ).to_json() + mapping["geo_organization"] = model_from_cache( + OrganizationReadSpec, id=obj.geo_organization.id + ) diff --git a/care/emr/resources/facility_organization/spec.py b/care/emr/resources/facility_organization/spec.py index 3dbb56bdaf..962d4fbf61 100644 --- a/care/emr/resources/facility_organization/spec.py +++ b/care/emr/resources/facility_organization/spec.py @@ -3,7 +3,7 @@ from pydantic import UUID4, field_validator, model_validator from care.emr.models.organization import FacilityOrganization -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, cacheable from care.emr.resources.user.spec import UserSpec from care.facility.models import Facility from care.security.authorization import AuthorizationController @@ -71,6 +71,7 @@ def perform_extra_deserialization(self, is_update, obj): obj.parent = None +@cacheable class FacilityOrganizationReadSpec(FacilityOrganizationBaseSpec): org_type: FacilityOrganizationTypeChoices parent: UUID4 | None = None @@ -85,11 +86,7 @@ class FacilityOrganizationReadSpec(FacilityOrganizationBaseSpec): def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id mapping["parent"] = obj.get_parent_json() - - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) class FacilityOrganizationRetrieveSpec(FacilityOrganizationReadSpec): diff --git a/care/emr/resources/file_upload/spec.py b/care/emr/resources/file_upload/spec.py index 41300f0183..a2d57e4d02 100644 --- a/care/emr/resources/file_upload/spec.py +++ b/care/emr/resources/file_upload/spec.py @@ -6,7 +6,7 @@ from pydantic import UUID4, field_validator from care.emr.models import FileUpload -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.user.spec import UserSpec from care.utils.models.validators import file_name_validator @@ -92,10 +92,10 @@ def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id mapping["extension"] = obj.get_extension() mapping["mime_type"] = obj.meta.get("mime_type") - if obj.created_by: - mapping["uploaded_by"] = UserSpec.serialize(obj.created_by) - if obj.archived_by: - mapping["archived_by"] = UserSpec.serialize(obj.archived_by) + if obj.created_by_id: + mapping["uploaded_by"] = model_from_cache(UserSpec, id=obj.created_by_id) + if obj.archived_by_id: + mapping["archived_by"] = model_from_cache(UserSpec, id=obj.archived_by_id) class FileUploadRetrieveSpec(FileUploadListSpec): @@ -112,8 +112,8 @@ def perform_extra_serialization(cls, mapping, obj): else: mapping["read_signed_url"] = obj.files_manager.read_signed_url(obj) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + if obj.updated_by_id: + mapping["updated_by"] = model_from_cache(UserSpec, id=obj.updated_by_id) class ConsentFileUploadCreateSpec(FileUploadBaseSpec): diff --git a/care/emr/resources/healthcare_service/spec.py b/care/emr/resources/healthcare_service/spec.py index 19a7925870..77088e27c1 100644 --- a/care/emr/resources/healthcare_service/spec.py +++ b/care/emr/resources/healthcare_service/spec.py @@ -3,9 +3,8 @@ from pydantic import UUID4 from care.emr.models.healthcare_service import HealthcareService -from care.emr.models.location import FacilityLocation from care.emr.models.organization import FacilityOrganization -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.facility_organization.spec import FacilityOrganizationReadSpec from care.emr.resources.healthcare_service.valueset import ( HEALTHCARE_SERVICE_TYPE_CODE_VALUESET, @@ -69,19 +68,20 @@ class HealthcareServiceRetrieveSpec(HealthcareServiceReadSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): + from care.emr.models.location import FacilityLocation + super().perform_extra_serialization(mapping, obj) locations = [] for location in obj.locations: try: + location_obj = FacilityLocation.objects.get(id=location) locations.append( - FacilityLocationListSpec.serialize( - FacilityLocation.objects.get(id=location) - ).to_json() + FacilityLocationListSpec.serialize(location_obj).to_json() ) except Exception: # noqa S110 pass mapping["locations"] = locations if obj.managing_organization: - mapping["managing_organization"] = FacilityOrganizationReadSpec.serialize( - obj.managing_organization - ).to_json() + mapping["managing_organization"] = model_from_cache( + FacilityOrganizationReadSpec, id=obj.managing_organization.id + ) diff --git a/care/emr/resources/inventory/supply_delivery/delivery_order.py b/care/emr/resources/inventory/supply_delivery/delivery_order.py index bbfc126de0..cfd90ca7fd 100644 --- a/care/emr/resources/inventory/supply_delivery/delivery_order.py +++ b/care/emr/resources/inventory/supply_delivery/delivery_order.py @@ -9,7 +9,7 @@ from care.emr.models.organization import Organization from care.emr.models.patient import Patient from care.emr.models.supply_delivery import DeliveryOrder -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.location.spec import FacilityLocationListSpec from care.emr.resources.organization.spec import ( OrganizationReadSpec, @@ -99,7 +99,9 @@ def perform_extra_serialization(cls, mapping, obj): obj.destination ).to_json() if obj.supplier: - mapping["supplier"] = OrganizationReadSpec.serialize(obj.supplier).to_json() + mapping["supplier"] = model_from_cache( + OrganizationReadSpec, id=obj.supplier.id + ) mapping["tags"] = SingleFacilityTagManager().render_tags(obj) if obj.patient: mapping["patient"] = PatientListSpec.serialize(obj.patient).to_json() diff --git a/care/emr/resources/inventory/supply_request/request_order.py b/care/emr/resources/inventory/supply_request/request_order.py index 835f38fcac..41c0c5056f 100644 --- a/care/emr/resources/inventory/supply_request/request_order.py +++ b/care/emr/resources/inventory/supply_request/request_order.py @@ -5,7 +5,7 @@ from care.emr.models.location import FacilityLocation from care.emr.models.supply_request import RequestOrder -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.location.spec import FacilityLocationListSpec from care.emr.resources.organization.spec import ( Organization, @@ -108,10 +108,15 @@ class SupplyRequestOrderReadSpec(BaseSupplyRequestOrderSpec): def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id if obj.supplier: - mapping["supplier"] = OrganizationReadSpec.serialize(obj.supplier).to_json() - if obj.origin: - mapping["origin"] = FacilityLocationListSpec.serialize(obj.origin).to_json() - mapping["destination"] = FacilityLocationListSpec.serialize( - obj.destination - ).to_json() + mapping["supplier"] = model_from_cache( + OrganizationReadSpec, id=obj.supplier.id + ) + if obj.origin_id: + origin = FacilityLocation.objects.get(id=obj.origin_id) + mapping["origin"] = FacilityLocationListSpec.serialize(origin).to_json() + if obj.destination_id: + destination = FacilityLocation.objects.get(id=obj.destination_id) + mapping["destination"] = FacilityLocationListSpec.serialize( + destination + ).to_json() mapping["tags"] = SingleFacilityTagManager().render_tags(obj) diff --git a/care/emr/resources/location/spec.py b/care/emr/resources/location/spec.py index 4a885b2b14..d58ef99149 100644 --- a/care/emr/resources/location/spec.py +++ b/care/emr/resources/location/spec.py @@ -7,7 +7,6 @@ from care.emr.models.location import FacilityLocation from care.emr.resources.base import EMRResource from care.emr.resources.common import Coding -from care.emr.resources.user.spec import UserSpec class LocationEncounterAvailabilityStatusChoices(str, Enum): @@ -151,10 +150,7 @@ class FacilityLocationRetrieveSpec(FacilityLocationListSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): super().perform_extra_serialization(mapping, obj) - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) class FacilityLocationEncounterBaseSpec(EMRResource): diff --git a/care/emr/resources/medication/administration/spec.py b/care/emr/resources/medication/administration/spec.py index 496e3c7847..c69e2ce569 100644 --- a/care/emr/resources/medication/administration/spec.py +++ b/care/emr/resources/medication/administration/spec.py @@ -191,5 +191,4 @@ def perform_extra_serialization(cls, mapping, obj): obj.administered_product ) - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) + cls.serialize_audit_users(mapping, obj) diff --git a/care/emr/resources/medication/dispense/dispense_order.py b/care/emr/resources/medication/dispense/dispense_order.py index 29f1263121..ef9af4f87e 100644 --- a/care/emr/resources/medication/dispense/dispense_order.py +++ b/care/emr/resources/medication/dispense/dispense_order.py @@ -60,7 +60,8 @@ class MedicationDispenseOrderReadSpec(BaseMedicationDispenseOrderSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id - mapping["location"] = FacilityLocationListSpec.serialize(obj.location).to_json() + location = FacilityLocation.objects.get(id=obj.location_id) + mapping["location"] = FacilityLocationListSpec.serialize(location).to_json() mapping["patient"] = PatientListSpec.serialize(obj.patient).to_json() @@ -74,5 +75,6 @@ class MedicationDispenseOrderRetrieveSpec(MedicationDispenseOrderReadSpec): def perform_extra_serialization(cls, mapping, obj): cls.serialize_audit_users(mapping, obj) mapping["id"] = obj.external_id - mapping["location"] = FacilityLocationListSpec.serialize(obj.location).to_json() + location = FacilityLocation.objects.get(id=obj.location_id) + mapping["location"] = FacilityLocationListSpec.serialize(location).to_json() mapping["patient"] = PatientRetrieveSpec.serialize(obj.patient).to_json() diff --git a/care/emr/resources/meta_artifact/spec.py b/care/emr/resources/meta_artifact/spec.py index cbdfcea3ed..b81ed62dea 100644 --- a/care/emr/resources/meta_artifact/spec.py +++ b/care/emr/resources/meta_artifact/spec.py @@ -42,10 +42,7 @@ class MetaArtifactReadSpec(MetaArtifactBaseSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) class MetaArtifactCreateSpec(MetaArtifactBaseSpec): diff --git a/care/emr/resources/notes/notes_spec.py b/care/emr/resources/notes/notes_spec.py index 98dcc09ac6..78cda54fbe 100644 --- a/care/emr/resources/notes/notes_spec.py +++ b/care/emr/resources/notes/notes_spec.py @@ -48,8 +48,4 @@ class NoteMessageReadSpec(NoteMessageSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id - - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by).to_json() - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by).to_json() + cls.serialize_audit_users(mapping, obj) diff --git a/care/emr/resources/notes/thread_spec.py b/care/emr/resources/notes/thread_spec.py index 904c00f8e7..4688538c42 100644 --- a/care/emr/resources/notes/thread_spec.py +++ b/care/emr/resources/notes/thread_spec.py @@ -44,8 +44,4 @@ class NoteThreadReadSpec(NoteThreadSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id - - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by).to_json() - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by).to_json() + cls.serialize_audit_users(mapping, obj) diff --git a/care/emr/resources/observation/spec.py b/care/emr/resources/observation/spec.py index 0fb06eda2c..9e52320576 100644 --- a/care/emr/resources/observation/spec.py +++ b/care/emr/resources/observation/spec.py @@ -4,7 +4,7 @@ from pydantic import UUID4, BaseModel, Field from care.emr.models.observation import Observation -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.common import Coding from care.emr.resources.common.codable_concept import CodeableConcept from care.emr.resources.observation.valueset import ( @@ -130,12 +130,11 @@ def perform_extra_serialization(cls, mapping, obj): mapping["patient"] = None mapping["questionnaire_response"] = None - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) - if obj.data_entered_by: - mapping["data_entered_by"] = UserSpec.serialize(obj.data_entered_by) + cls.serialize_audit_users(mapping, obj) + if obj.data_entered_by_id: + mapping["data_entered_by"] = model_from_cache( + UserSpec, id=obj.data_entered_by_id + ) class ObservationRetrieveSpec(ObservationReadSpec): diff --git a/care/emr/resources/organization/spec.py b/care/emr/resources/organization/spec.py index c90c9f41e8..3cf001679c 100644 --- a/care/emr/resources/organization/spec.py +++ b/care/emr/resources/organization/spec.py @@ -3,7 +3,7 @@ from pydantic import UUID4, model_validator from care.emr.models.organization import Organization -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, cacheable from care.security.authorization import AuthorizationController @@ -50,6 +50,7 @@ def perform_extra_deserialization(self, is_update, obj): obj.parent = None +@cacheable class OrganizationReadSpec(OrganizationBaseSpec): level_cache: int = 0 system_generated: bool diff --git a/care/emr/resources/patient/spec.py b/care/emr/resources/patient/spec.py index 955b639530..7380a47a42 100644 --- a/care/emr/resources/patient/spec.py +++ b/care/emr/resources/patient/spec.py @@ -260,18 +260,15 @@ class PatientRetrieveSpec(PatientListSpec, PatientPermissionsMixin): @classmethod def perform_extra_serialization(cls, mapping, obj, *args, **kwargs): + from care.emr.resources.base import model_from_cache from care.emr.resources.organization.spec import OrganizationReadSpec - from care.emr.resources.user.spec import UserSpec super().perform_extra_serialization(mapping, obj, *args, **kwargs) if obj.geo_organization: - mapping["geo_organization"] = OrganizationReadSpec.serialize( - obj.geo_organization - ).to_json() - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by).to_json() - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by).to_json() + mapping["geo_organization"] = model_from_cache( + OrganizationReadSpec, id=obj.geo_organization.id + ) + cls.serialize_audit_users(mapping, obj) if obj.instance_identifiers: mapping["instance_identifiers"] = [ { diff --git a/care/emr/resources/questionnaire/spec.py b/care/emr/resources/questionnaire/spec.py index 7acd55fa75..5b1c050020 100644 --- a/care/emr/resources/questionnaire/spec.py +++ b/care/emr/resources/questionnaire/spec.py @@ -290,10 +290,7 @@ def perform_extra_serialization(cls, mapping, obj): for tag in obj.tags: tags.append(QuestionnaireTag.get_tag(tag)) mapping["tags"] = tags - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) # Add this to handle recursive Question type diff --git a/care/emr/resources/questionnaire_response/spec.py b/care/emr/resources/questionnaire_response/spec.py index dbb29fd63d..4a4d669c31 100644 --- a/care/emr/resources/questionnaire_response/spec.py +++ b/care/emr/resources/questionnaire_response/spec.py @@ -73,7 +73,4 @@ def perform_extra_serialization(cls, mapping, obj): mapping["encounter"] = obj.encounter.external_id else: mapping["encounter"] = None - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) diff --git a/care/emr/resources/resource_request/spec.py b/care/emr/resources/resource_request/spec.py index f92798c867..4ac181d702 100644 --- a/care/emr/resources/resource_request/spec.py +++ b/care/emr/resources/resource_request/spec.py @@ -6,7 +6,7 @@ from care.emr.models import Patient from care.emr.models.organization import FacilityOrganizationUser from care.emr.models.resource_request import ResourceRequest, ResourceRequestComment -from care.emr.resources.base import EMRResource +from care.emr.resources.base import EMRResource, model_from_cache from care.emr.resources.facility.spec import FacilityReadSpec from care.emr.resources.patient.spec import PatientListSpec from care.emr.resources.user.spec import UserSpec @@ -147,13 +147,10 @@ def perform_extra_serialization(cls, mapping, obj): mapping["related_patient"] = PatientListSpec.serialize( obj.related_patient ).to_json() - if obj.assigned_to: - mapping["assigned_to"] = UserSpec.serialize(obj.assigned_to).to_json() + if obj.assigned_to_id: + mapping["assigned_to"] = model_from_cache(UserSpec, id=obj.assigned_to_id) - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) class ResourceRequestCommentBaseSpec(EMRResource): @@ -173,8 +170,7 @@ class ResourceRequestCommentListSpec(ResourceRequestCommentBaseSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) + cls.serialize_audit_users(mapping, obj) class ResourceRequestCommentRetrieveSpec(ResourceRequestCommentListSpec): diff --git a/care/emr/resources/scheduling/resource/spec.py b/care/emr/resources/scheduling/resource/spec.py index 63b43c0b0c..3026b20c07 100644 --- a/care/emr/resources/scheduling/resource/spec.py +++ b/care/emr/resources/scheduling/resource/spec.py @@ -1,3 +1,4 @@ +from care.emr.models.location import FacilityLocation from care.emr.resources.base import model_from_cache from care.emr.resources.healthcare_service.spec import HealthcareServiceReadSpec from care.emr.resources.location.spec import FacilityLocationListSpec @@ -11,5 +12,6 @@ def serialize_resource(obj): if obj.resource_type == SchedulableResourceTypeOptions.healthcare_service.value: return HealthcareServiceReadSpec.serialize(obj.healthcare_service).to_json() if obj.resource_type == SchedulableResourceTypeOptions.location.value: - return FacilityLocationListSpec.serialize(obj.location).to_json() + location = FacilityLocation.objects.get(id=obj.location_id) + return FacilityLocationListSpec.serialize(location).to_json() return {} diff --git a/care/emr/resources/service_request/spec.py b/care/emr/resources/service_request/spec.py index 00cedd92c6..337d313e7e 100644 --- a/care/emr/resources/service_request/spec.py +++ b/care/emr/resources/service_request/spec.py @@ -167,8 +167,10 @@ class ServiceRequestRetrieveSpec(ServiceRequestReadSpec): def perform_extra_serialization(cls, mapping, obj): super().perform_extra_serialization(mapping, obj) locations = [] - for location in FacilityLocation.objects.filter(id__in=obj.locations): - locations.append(FacilityLocationListSpec.serialize(location).to_json()) + for location_id in obj.locations: + location = FacilityLocation.objects.filter(id=location_id).first() + if location: + locations.append(FacilityLocationListSpec.serialize(location).to_json()) mapping["locations"] = locations if obj.healthcare_service: diff --git a/care/emr/resources/tag/config_spec.py b/care/emr/resources/tag/config_spec.py index 47f6f5129f..f4a3922494 100644 --- a/care/emr/resources/tag/config_spec.py +++ b/care/emr/resources/tag/config_spec.py @@ -176,6 +176,7 @@ class TagConfigRetrieveSpec(TagConfigReadSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): + from care.emr.resources.base import model_from_cache from care.emr.resources.facility_organization.spec import ( FacilityOrganizationReadSpec, ) @@ -184,13 +185,13 @@ def perform_extra_serialization(cls, mapping, obj): super().perform_extra_serialization(mapping, obj) cls.serialize_audit_users(mapping, obj) if obj.facility_organization: - mapping["facility_organization"] = FacilityOrganizationReadSpec.serialize( - obj.facility_organization - ).to_json() + mapping["facility_organization"] = model_from_cache( + FacilityOrganizationReadSpec, id=obj.facility_organization.id + ) if obj.organization: - mapping["organization"] = OrganizationReadSpec.serialize( - obj.organization - ).to_json() + mapping["organization"] = model_from_cache( + OrganizationReadSpec, id=obj.organization.id + ) post_save.connect( diff --git a/care/emr/resources/user/spec.py b/care/emr/resources/user/spec.py index 0e84295d9a..1fa17789dc 100644 --- a/care/emr/resources/user/spec.py +++ b/care/emr/resources/user/spec.py @@ -153,10 +153,10 @@ def perform_extra_serialization(cls, mapping, obj: User): super().perform_extra_serialization(mapping, obj) if obj.created_by_id: mapping["created_by"] = model_from_cache(UserSpec, id=obj.created_by_id) - if obj.geo_organization: - mapping["geo_organization"] = OrganizationReadSpec.serialize( - obj.geo_organization - ).to_json() + if obj.geo_organization_id: + mapping["geo_organization"] = model_from_cache( + OrganizationReadSpec, id=obj.geo_organization_id + ) mapping["flags"] = obj.get_all_flags() @@ -184,15 +184,20 @@ def perform_extra_serialization(cls, mapping, obj: User) -> None: super().perform_extra_serialization(mapping, obj) if obj.is_superuser: - organizations = Organization.objects.filter(parent__isnull=True) + organization_ids = list( + Organization.objects.filter(parent__isnull=True).values_list( + "id", flat=True + ) + ) else: - organizations = Organization.objects.filter( - id__in=OrganizationUser.objects.filter(user=obj).values_list( + organization_ids = list( + OrganizationUser.objects.filter(user=obj).values_list( "organization_id", flat=True ) ) mapping["organizations"] = [ - OrganizationReadSpec.serialize(obj).to_json() for obj in organizations + model_from_cache(OrganizationReadSpec, id=org_id) + for org_id in organization_ids ] user_facilities = Facility.objects.filter( diff --git a/care/emr/resources/valueset/spec.py b/care/emr/resources/valueset/spec.py index 95137615f5..680af8d051 100644 --- a/care/emr/resources/valueset/spec.py +++ b/care/emr/resources/valueset/spec.py @@ -66,10 +66,7 @@ class ValueSetReadSpec(ValueSetBaseSpec): @classmethod def perform_extra_serialization(cls, mapping, obj): mapping["id"] = obj.external_id - if obj.created_by: - mapping["created_by"] = UserSpec.serialize(obj.created_by) - if obj.updated_by: - mapping["updated_by"] = UserSpec.serialize(obj.updated_by) + cls.serialize_audit_users(mapping, obj) ValueSetSpec.model_rebuild()