diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 4a64b0034f..1e6a1b3962 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -131,7 +131,9 @@ class Meta: phone_number = PhoneNumberIsPossibleField() - facility = ExternalIdSerializerField(queryset=Facility.objects.all(), required=False) + facility = ExternalIdSerializerField( + queryset=Facility.objects.all(), required=False + ) medical_history = serializers.ListSerializer( child=MedicalHistorySerializer(), required=False ) @@ -385,11 +387,11 @@ class PatientSearchSerializer(serializers.ModelSerializer): class Meta: model = PatientSearch exclude = ( - "date_of_birth", - "year_of_birth", - "external_id", - "id", - ) + TIMESTAMP_FIELDS + "date_of_birth", + "year_of_birth", + "external_id", + "id", + ) + TIMESTAMP_FIELDS class PatientTransferSerializer(serializers.ModelSerializer): diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 60c4fe49b9..d3cbadda82 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -19,8 +19,13 @@ Ward, pretty_boolean, ) -from care.facility.models.mixins.permissions.facility import FacilityRelatedPermissionMixin -from care.facility.models.mixins.permissions.patient import PatientPermissionMixin, PatientRelatedPermissionMixin +from care.facility.models.mixins.permissions.facility import ( + FacilityRelatedPermissionMixin, +) +from care.facility.models.mixins.permissions.patient import ( + PatientPermissionMixin, + PatientRelatedPermissionMixin, +) from care.facility.models.patient_base import ( BLOOD_GROUP_CHOICES, DISEASE_STATUS_CHOICES, @@ -30,7 +35,12 @@ REVERSE_SYMPTOM_CATEGORY_CHOICES, ) from care.facility.models.patient_consultation import PatientConsultation -from care.users.models import GENDER_CHOICES, REVERSE_GENDER_CHOICES, User, phone_number_regex +from care.users.models import ( + GENDER_CHOICES, + REVERSE_GENDER_CHOICES, + User, + phone_number_regex, +) from care.utils.models.base import BaseManager, BaseModel from care.utils.models.jsonfield import JSONField @@ -94,7 +104,9 @@ class TestTypeEnum(enum.Enum): null=True, related_name="nearest_facility", ) - meta_info = models.OneToOneField("PatientMetaInfo", on_delete=models.SET_NULL, null=True) + meta_info = models.OneToOneField( + "PatientMetaInfo", on_delete=models.SET_NULL, null=True + ) # name_old = EncryptedCharField(max_length=200, default="") name = models.CharField(max_length=200, default="") @@ -103,9 +115,13 @@ class TestTypeEnum(enum.Enum): gender = models.IntegerField(choices=GENDER_CHOICES, blank=False) # phone_number_old = EncryptedCharField(max_length=14, validators=[phone_number_regex], default="") - phone_number = models.CharField(max_length=14, validators=[phone_number_regex], default="") + phone_number = models.CharField( + max_length=14, validators=[phone_number_regex], default="" + ) - emergency_phone_number = models.CharField(max_length=14, validators=[phone_number_regex], default="") + emergency_phone_number = models.CharField( + max_length=14, validators=[phone_number_regex], default="" + ) # address_old = EncryptedTextField(default="") address = models.TextField(default="") @@ -116,18 +132,16 @@ class TestTypeEnum(enum.Enum): date_of_birth = models.DateField(default=None, null=True) year_of_birth = models.IntegerField(default=0, null=True) - nationality = models.CharField(max_length=255, default="", verbose_name="Nationality of Patient") - passport_no = models.CharField(max_length=255, default="", verbose_name="Passport Number of Foreign Patients") + nationality = models.CharField( + max_length=255, default="", verbose_name="Nationality of Patient" + ) + passport_no = models.CharField( + max_length=255, default="", verbose_name="Passport Number of Foreign Patients" + ) # aadhar_no = models.CharField(max_length=255, default="", verbose_name="Aadhar Number of Patient") - is_medical_worker = models.BooleanField(default=False, verbose_name="Is the Patient a Medical Worker") - - blood_group = models.CharField( - choices=BLOOD_GROUP_CHOICES, - null=True, - blank=False, - max_length=4, - verbose_name="Blood Group of Patient", + is_medical_worker = models.BooleanField( + default=False, verbose_name="Is the Patient a Medical Worker" ) contact_with_confirmed_carrier = models.BooleanField( @@ -148,26 +162,40 @@ class TestTypeEnum(enum.Enum): verbose_name="Countries Patient has Travelled to", editable=False, ) - countries_travelled = JSONField(null=True, blank=True, verbose_name="Countries Patient has Travelled to") + countries_travelled = JSONField( + null=True, blank=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(default="", blank=True, verbose_name="Patient's Known Allergies") - - present_health = models.TextField(default="", blank=True, verbose_name="Patient's Current Health Details") - ongoing_medication = models.TextField(default="", blank=True, verbose_name="Already pescribed medication if any") - has_SARI = models.BooleanField(default=False, verbose_name="Does the Patient Suffer from SARI") + present_health = models.TextField( + default="", blank=True, verbose_name="Patient's Current Health Details" + ) + ongoing_medication = models.TextField( + default="", blank=True, 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 ?") + is_antenatal = models.BooleanField( + default=None, verbose_name="Does the patient require Prenatal Care ?" + ) - ward_old = models.CharField(max_length=255, default="", verbose_name="Ward of Patient", blank=False) + ward_old = models.CharField( + max_length=255, default="", verbose_name="Ward of Patient", blank=False + ) ward = models.ForeignKey(Ward, on_delete=models.SET_NULL, null=True, blank=True) - local_body = models.ForeignKey(LocalBody, on_delete=models.SET_NULL, null=True, blank=True) - district = models.ForeignKey(District, on_delete=models.SET_NULL, null=True, blank=True) + local_body = models.ForeignKey( + LocalBody, on_delete=models.SET_NULL, null=True, blank=True + ) + district = models.ForeignKey( + District, on_delete=models.SET_NULL, null=True, blank=True + ) state = models.ForeignKey(State, on_delete=models.SET_NULL, null=True, blank=True) is_migrant_worker = models.BooleanField( @@ -200,16 +228,24 @@ class TestTypeEnum(enum.Enum): related_name="patient_last_edited_by", ) - action = models.IntegerField(choices=ActionChoices, default=ActionEnum.PENDING.value) - review_time = models.DateTimeField(null=True, blank=True, verbose_name="Patient's next review time") + action = models.IntegerField( + choices=ActionChoices, default=ActionEnum.PENDING.value + ) + review_time = models.DateTimeField( + null=True, blank=True, verbose_name="Patient's next review time" + ) - created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="patient_created_by") + created_by = models.ForeignKey( + User, on_delete=models.SET_NULL, null=True, related_name="patient_created_by" + ) is_active = models.BooleanField( default=True, help_text="Not active when discharged, or removed from the watchlist", ) - patient_search_id = EncryptedIntegerField(help_text="FKey to PatientSearch", null=True) + patient_search_id = EncryptedIntegerField( + help_text="FKey to PatientSearch", null=True + ) date_of_receipt_of_information = models.DateTimeField( null=True, blank=True, verbose_name="Patient's information received date" ) @@ -217,13 +253,19 @@ class TestTypeEnum(enum.Enum): test_id = models.CharField(default="", max_length=100, null=True, blank=True) # Issue #600 Care_Fe - date_of_test = models.DateTimeField(null=True, blank=True, verbose_name="Patient's test Date") + date_of_test = models.DateTimeField( + null=True, blank=True, verbose_name="Patient's test Date" + ) srf_id = models.CharField(max_length=200, blank=True, default="") - test_type = models.IntegerField(choices=TestTypeChoices, default=TestTypeEnum.UNK.value) + test_type = models.IntegerField( + choices=TestTypeChoices, default=TestTypeEnum.UNK.value + ) allow_transfer = models.BooleanField(default=False) - last_consultation = models.ForeignKey(PatientConsultation, on_delete=models.SET_NULL, null=True, default=None) + last_consultation = models.ForeignKey( + PatientConsultation, on_delete=models.SET_NULL, null=True, default=None + ) will_donate_blood = models.BooleanField( default=None, @@ -273,7 +315,9 @@ class TestTypeEnum(enum.Enum): null=True, blank=True, ) - date_of_result = models.DateTimeField(null=True, blank=True, default=None, verbose_name="Patient's result Date") + date_of_result = models.DateTimeField( + null=True, blank=True, default=None, verbose_name="Patient's result Date" + ) number_of_primary_contacts = models.IntegerField( null=True, default=None, blank=True, verbose_name="Number of Primary Contacts" ) @@ -283,11 +327,18 @@ class TestTypeEnum(enum.Enum): # IDSP Requirements End # Vaccination Fields - is_vaccinated = models.BooleanField(default=False, verbose_name="Is the Patient Vaccinated Against COVID-19") + is_vaccinated = models.BooleanField( + default=False, verbose_name="Is the Patient Vaccinated Against COVID-19" + ) number_of_doses = models.PositiveIntegerField( - default=0, null=False, blank=False, validators=[MinValueValidator(0), MaxValueValidator(3)] + default=0, + null=False, + blank=False, + validators=[MinValueValidator(0), MaxValueValidator(3)], + ) + vaccine_name = models.CharField( + choices=vaccineChoices, default=None, null=True, blank=False, max_length=15 ) - vaccine_name = models.CharField(choices=vaccineChoices, default=None, null=True, blank=False, max_length=15) covin_id = models.CharField( max_length=15, @@ -296,7 +347,9 @@ class TestTypeEnum(enum.Enum): blank=True, verbose_name="COVID-19 Vaccination ID", ) - last_vaccinated_date = models.DateTimeField(null=True, blank=True, verbose_name="Date Last Vaccinated") + last_vaccinated_date = models.DateTimeField( + null=True, blank=True, verbose_name="Date Last Vaccinated" + ) # Extras cluster_name = models.CharField( @@ -318,7 +371,11 @@ class TestTypeEnum(enum.Enum): # Permission Scopes assigned_to = models.ForeignKey( - User, on_delete=models.SET_NULL, null=True, blank="True", related_name="root_patient_assigned_to" + User, + on_delete=models.SET_NULL, + null=True, + blank="True", + related_name="root_patient_assigned_to", ) history = HistoricalRecords(excluded_fields=["patient_search_id", "meta_info"]) @@ -359,7 +416,9 @@ def save(self, *args, **kwargs) -> None: self.state = self.district.state self.year_of_birth = ( - self.date_of_birth.year if self.date_of_birth is not None else datetime.datetime.now().year - self.age + self.date_of_birth.year + if self.date_of_birth is not None + else datetime.datetime.now().year - self.age ) today = datetime.date.today() @@ -368,7 +427,10 @@ def save(self, *args, **kwargs) -> None: self.age = ( today.year - self.date_of_birth.year - - ((today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day)) + - ( + (today.month, today.day) + < (self.date_of_birth.month, self.date_of_birth.day) + ) ) elif self.year_of_birth: self.age = today.year - self.year_of_birth @@ -490,8 +552,12 @@ def save(self, *args, **kwargs) -> None: "is_declared_positive": pretty_boolean, "is_vaccinated": pretty_boolean, # Consultation Data - "last_consultation__category": (lambda x: REVERSE_SYMPTOM_CATEGORY_CHOICES.get(x, "-")), - "last_consultation__suggestion": (lambda x: PatientConsultation.REVERSE_SUGGESTION_CHOICES.get(x, "-")), + "last_consultation__category": ( + lambda x: REVERSE_SYMPTOM_CATEGORY_CHOICES.get(x, "-") + ), + "last_consultation__suggestion": ( + lambda x: PatientConsultation.REVERSE_SUGGESTION_CHOICES.get(x, "-") + ), "last_consultation__admitted": pretty_boolean, "last_consultation__admitted_to": (lambda x: REVERSE_ADMIT_CHOICES.get(x, "-")), } @@ -521,9 +587,15 @@ class Meta: @staticmethod def has_read_permission(request): - if request.user.is_superuser or request.user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"]: + 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: + elif ( + request.user.user_type >= User.TYPE_VALUE_MAP["Staff"] + and request.user.verified + ): return True return False @@ -582,7 +654,9 @@ class ModeOfContactEnum(enum.IntEnum): RelationChoices = [(item.value, item.name) for item in RelationEnum] ModeOfContactChoices = [(item.value, item.name) for item in ModeOfContactEnum] - patient = models.ForeignKey(PatientRegistration, on_delete=models.PROTECT, related_name="contacted_patients") + patient = models.ForeignKey( + PatientRegistration, on_delete=models.PROTECT, related_name="contacted_patients" + ) patient_in_contact = models.ForeignKey( PatientRegistration, on_delete=models.PROTECT, @@ -605,7 +679,9 @@ class ModeOfContactEnum(enum.IntEnum): class Disease(models.Model): - patient = models.ForeignKey(PatientRegistration, on_delete=models.CASCADE, related_name="medical_history") + patient = models.ForeignKey( + PatientRegistration, on_delete=models.CASCADE, related_name="medical_history" + ) disease = models.IntegerField(choices=DISEASE_CHOICES) details = models.TextField(blank=True, null=True) deleted = models.BooleanField(default=False) @@ -613,7 +689,11 @@ class Disease(models.Model): objects = BaseManager() class Meta: - indexes = [PartialIndex(fields=["patient", "disease"], unique=True, where=PQ(deleted=False))] + indexes = [ + PartialIndex( + fields=["patient", "disease"], unique=True, where=PQ(deleted=False) + ) + ] def __str__(self): return self.patient.name + " - " + self.get_disease_display() @@ -656,8 +736,12 @@ class PatientMobileOTP(BaseModel): class PatientNotes(FacilityBaseModel, PatientRelatedPermissionMixin): - patient = models.ForeignKey(PatientRegistration, on_delete=models.PROTECT, null=False, blank=False) - facility = models.ForeignKey(Facility, on_delete=models.PROTECT, null=False, blank=False) + patient = models.ForeignKey( + PatientRegistration, on_delete=models.PROTECT, null=False, blank=False + ) + facility = models.ForeignKey( + Facility, on_delete=models.PROTECT, null=False, blank=False + ) created_by = models.ForeignKey( User, on_delete=models.SET_NULL,