class PatientSearch(models.Model): 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() 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 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 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() 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 @property def facility_id(self): facility_ids = PatientRegistration.objects.filter(id=self.patient_id).values_list("facility__external_id") return facility_ids[0][0] if len(facility_ids) > 0 else None
class MerchantItem(models.Model): Adult_or_Child = ( ('A', 'Adult'), ('C', 'Child'), ('B', 'Both'), ) Gender_Allowed = ( ('M', 'Male'), ('F', 'Female'), ('B', 'Both'), ) merchant_code = models.ForeignKey(Merchant, on_delete=models.CASCADE, related_name='merchantcode') item_code = models.CharField(primary_key=True, unique=True, max_length=50) description = EncryptedCharField(max_length=200) adult_child = EncryptedCharField(max_length=2, choices=Adult_or_Child) gender_allowed = EncryptedCharField(max_length=1, choices=Gender_Allowed) quantity = EncryptedIntegerField(default=0, blank=True) price = models.DecimalField(decimal_places=2, default=0.00, max_digits=10, blank=True) discount = models.DecimalField(decimal_places=2, default=0.00, max_digits=10, blank=True) def __str__(self): return self.item_code
class Employee(models.Model): history = AuditlogHistoryField(pk_indexable=False) EmployeeName = EncryptedCharField(max_length=1000) EmployeeId = models.IntegerField(primary_key=True) EmployeeSSN = EncryptedIntegerField() EmployeePosition = EncryptedCharField(max_length=1000) EmployeeSalary = EncryptedIntegerField DepartId = models.ForeignKey(Department) UniId = models.ForeignKey(University) def __unicode__(self): return self.EmployeeName class Meta: db_table = 'employee'
class PurchasedContent(models.Model): purchased_item = models.ForeignKey(PurchasedCommodity, on_delete=models.CASCADE, related_name='purch_content') hundredgramqty = EncryptedIntegerField(default=0) hundredgramtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) twohundredgramqty = EncryptedIntegerField(default=0) twohundredgramtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) fivehundredgramqty = EncryptedIntegerField(default=0) fivehundredgramtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) onekgqty = EncryptedIntegerField(default=0) onekgtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) fivekgqty = EncryptedIntegerField(default=0) fivekgtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) twentyfivekgqty = EncryptedIntegerField(default=0) twentyfivekgtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) fiftykgqty = EncryptedIntegerField(default=0) fiftykgtotprice = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) totalcommamt = models.DecimalField(decimal_places=2, max_digits=10, default=0.0) total_packets = EncryptedIntegerField(default=0) def __str__(self): return str(self.purchased_item.purchased_groc.profile.first_name ) + ' bought ' + str(self.total_packets) + ' ' + str( self.purchased_item) + ' packets' class Meta: verbose_name_plural = "Purchased Contents"
class Person(models.Model): class Meta: verbose_name = 'Информации ползователя' verbose_name_plural = 'Информация' last_name = models.CharField('Фамилия', max_length=125) first_name = models.CharField('Имя', max_length=125) patronymic_name = models.CharField('Отчество', max_length=125) address = models.CharField('Адрес', max_length=255) inn = EncryptedIntegerField('ИНН') phone_regex = RegexValidator( regex=r'^\+?1?\d{5,14}$', message= "Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed." ) phone_number = models.CharField('Телефон', validators=[phone_regex], max_length=14, blank=True) # validators should be a list def __str__(self): return self.last_name
class PatientRegistration(PatientBaseModel, PatientPermissionMixin): # fields in the PatientSearch model PATIENT_SEARCH_KEYS = [ "name", "gender", "phone_number", "date_of_birth", "year_of_birth", "state_id", ] class SourceEnum(enum.Enum): CARE = 10 COVID_TRACKER = 20 STAY = 30 SourceChoices = [(e.value, e.name) for e in SourceEnum] class ActionEnum(enum.Enum): PENDING = 10 SPECIALIST_REQUIRED = 30 PLAN_FOR_HOME_CARE = 40 FOLLOW_UP_NOT_REQUIRED = 50 COMPLETE = 60 REVIEW = 70 NOT_REACHABLE = 80 ActionChoices = [(e.value, e.name) for e in ActionEnum] class TestTypeEnum(enum.Enum): UNK = 10 ANTIGEN = 20 RTPCR = 30 CBNAAT = 40 TRUENAT = 50 TestTypeChoices = [(e.value, e.name) for e in TestTypeEnum] source = models.IntegerField(choices=SourceChoices, default=SourceEnum.CARE.value) facility = models.ForeignKey("Facility", on_delete=models.SET_NULL, null=True) nearest_facility = models.ForeignKey( "Facility", on_delete=models.SET_NULL, null=True, related_name="nearest_facility", ) 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="") age = models.PositiveIntegerField(null=True, blank=True) 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="") emergency_phone_number = models.CharField(max_length=14, validators=[phone_number_regex], default="") # address_old = EncryptedTextField(default="") address = models.TextField(default="") pincode = models.IntegerField(default=0, blank=True, null=True) 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") # 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", ) 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(null=True, blank=True) past_travel = models.BooleanField( default=False, verbose_name="Travelled to Any Foreign Countries in the last 28 Days", ) countries_travelled_old = models.TextField( null=True, blank=True, verbose_name="Countries Patient has Travelled to", editable=False, ) 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") is_antenatal = models.BooleanField( default=False, verbose_name="Does the patient require Prenatal Care ?") 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) state = models.ForeignKey(State, on_delete=models.SET_NULL, null=True, blank=True) is_migrant_worker = models.BooleanField( default=False, verbose_name="Is Patient a Migrant Worker", ) disease_status = models.IntegerField( choices=DISEASE_STATUS_CHOICES, default=1, blank=True, verbose_name="Disease Status", ) number_of_aged_dependents = models.IntegerField( default=0, verbose_name="Number of people aged above 60 living with the patient", blank=True, ) number_of_chronic_diseased_dependents = models.IntegerField( default=0, verbose_name= "Number of people who have chronic diseases living with the patient", blank=True, ) last_edited = models.ForeignKey( User, on_delete=models.SET_NULL, null=True, 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") 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) date_of_receipt_of_information = models.DateTimeField( null=True, blank=True, verbose_name="Patient's information received date") 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") srf_id = models.CharField(max_length=200, blank=True, default="") 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) 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", ) # IDSP REQUIREMENTS village = models.CharField( max_length=255, default=None, verbose_name="Vilalge Name of Patient (IDSP Req)", null=True, blank=True, ) designation_of_health_care_worker = models.CharField( max_length=255, default=None, verbose_name="Designation of Health Care Worker (IDSP Req)", null=True, blank=True, ) instituion_of_health_care_worker = models.CharField( max_length=255, default=None, verbose_name="Institution of Healtcare Worker (IDSP Req)", null=True, blank=True, ) transit_details = models.CharField( max_length=255, default=None, verbose_name="Transit Details (IDSP Req)", null=True, blank=True, ) frontline_worker = models.CharField( max_length=255, default=None, verbose_name="Front Line Worker (IDSP Req)", null=True, blank=True, ) 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") number_of_secondary_contacts = models.IntegerField( null=True, default=None, blank=True, verbose_name="Number of Secondary Contacts") # IDSP Requirements End # Vaccination Fields is_vaccinated = models.BooleanField( default=False, verbose_name="Is the Patient Vaccinated Against COVID-19") covin_id = models.CharField( max_length=15, default=None, null=True, blank=True, verbose_name="COVID-19 Vaccination ID", ) # Extras cluster_name = models.CharField( max_length=255, default=None, verbose_name="Name/ Cluster of Contact", null=True, blank=True, ) is_declared_positive = models.BooleanField( default=None, null=True, verbose_name="Is Patient Declared Positive", ) date_declared_positive = models.DateTimeField( null=True, blank=True, verbose_name="Date Patient is Declared Positive") history = HistoricalRecords( excluded_fields=["patient_search_id", "meta_info"]) objects = BaseManager() def __str__(self): return "{} - {} - {}".format(self.name, self.age, self.get_gender_display()) @property def tele_consultation_history(self): return self.patientteleconsultation_set.order_by("-id") def _alias_recovery_to_recovered(self) -> None: if self.disease_status == DiseaseStatusEnum.RECOVERY.value: self.disease_status = DiseaseStatusEnum.RECOVERED.value def save(self, *args, **kwargs) -> None: """ While saving, if the local body is not null, then district will be local body's district Overriding save will help in a collision where the local body's district and district fields are different. It also aliases the DiseaseStatus RECOVERED to RECOVERY It also creates/updates the PatientSearch model Parameters ---------- args: list of args - not used kwargs: keyword args - not used Returns ------- None """ if self.local_body is not None: self.district = self.local_body.district if self.district is not 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) today = datetime.date.today() if self.date_of_birth: self.age = (today.year - self.date_of_birth.year - ((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 self.date_of_receipt_of_information = ( self.date_of_receipt_of_information if self.date_of_receipt_of_information is not 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 = { "external_id": "Patient ID", "name": "Patient Name", "phone_number": "Patient Phone Number", "date_of_birth": "Date of Birth", # "year_of_birth": "Year of Birth", "facility__name": "Facility Name", # "nearest_facility__name": "Nearest Facility", "age": "Age", "gender": "Gender", "ward__name": "Ward Name", "ward__number": "Ward Number", "local_body__name": "Local Body", "district__name": "District", "state__name": "State", "address": "Address", "nationality": "Nationality", "disease_status": "Disease Status", # "state_test_id": "State Test ID", "last_consultation__admitted": "Admission Status", "last_consultation__admitted_to": "Admission Room Type", # Reffered or transferred # remarks "number_of_aged_dependents": "Number of people aged above 60 living with the patient", "number_of_chronic_diseased_dependents": "Number of people who have chronic diseases living with the patient", "blood_group": "Blood Group", "is_medical_worker": "Is the Patient a Medical Worker", "contact_with_confirmed_carrier": "Confirmed Contact with a Covid19 Carrier", "contact_with_suspected_carrier": "Suspected Contact with a Covid19 Carrier", "estimated_contact_date": "Estimated Contact Date", "past_travel": "Travelled to Any Foreign Countries in the last 28 Days", "countries_travelled": "Countries Patient has Travelled to", "date_of_return": "Return Date from the Last Country if Travelled", "is_migrant_worker": "Is the Patient a Migrant Worker", "present_health": "Patient's Current Health Details", "ongoing_medication": "Already pescribed medication if any", "has_SARI": "Does the Patient Suffer from SARI", "date_of_receipt_of_information": "Patient's information received date", "will_donate_blood": "Will Patient Donate Blood?", "fit_for_blood_donation": "Is Patient Fit for Blood Donation?", "date_of_test": "Date of Sample Test", "srf_id": "SRF Test Id", # IDSP Data "village": "Village", "designation_of_health_care_worker": "Designation of Health Care Worker", "instituion_of_health_care_worker": "Institution of Health Care Worker", "transit_details": "Transit Details", "frontline_worker": "FrontLine Worker", "date_of_result": "Date of Result", "number_of_primary_contacts": "Number of Primary Contacts", "number_of_secondary_contacts": "Number of Secondary Contacts", "cluster_name": "Name/ Cluster of Contact", "is_declared_positive": "Is Patient Declared Positive", "date_declared_positive": "Date Patient is Declared Positive", # Consultation Data "last_consultation__admission_date": "Date of Admission", "last_consultation__symptoms_onset_date": "Date of Onset of Symptoms", "last_consultation__symptoms": "Symptoms at time of consultation", "last_consultation__category": "Category", "last_consultation__examination_details": "Examination Details", "last_consultation__suggestion": "Suggestion", "last_consultation__created_date": "Date of Consultation", "last_consultation__discharge_date": "Date of Discharge", } CSV_MAKE_PRETTY = { "gender": (lambda x: REVERSE_GENDER_CHOICES[x]), "blood_group": (lambda x: REVERSE_BLOOD_GROUP_CHOICES[x]), "disease_status": (lambda x: REVERSE_DISEASE_STATUS_CHOICES[x]), "is_medical_worker": pretty_boolean, "will_donate_blood": pretty_boolean, "fit_for_blood_donation": pretty_boolean, "is_migrant_worker": pretty_boolean, "is_declared_positive": 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__admitted": pretty_boolean, "last_consultation__admitted_to": (lambda x: REVERSE_ADMIT_CHOICES.get(x, "-")), }
class PatientRegistration(PatientBaseModel): # fields in the PatientSearch model PATIENT_SEARCH_KEYS = [ "name", "gender", "phone_number", "date_of_birth", "year_of_birth", "state_id" ] def __init__(self, *args, **kwargs): super(PatientRegistration, self).__init__(*args, **kwargs) self._diff = {} facility = models.ForeignKey("Facility", on_delete=models.SET_NULL, null=True) name = EncryptedCharField(max_length=200) age = models.PositiveIntegerField() gender = models.IntegerField(choices=GENDER_CHOICES, blank=False) phone_number = EncryptedCharField(max_length=14, validators=[phone_number_regex]) address = EncryptedTextField(default="") 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") 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=True, max_length=4, 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(null=True, blank=True) past_travel = models.BooleanField( default=False, verbose_name="Travelled to Any Foreign Countries in the last 28 Days", ) countries_travelled = models.TextField( default="", 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") 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") 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) disease_status = models.IntegerField(choices=DISEASE_STATUS_CHOICES, default=1, blank=True, verbose_name="Disease Status") number_of_aged_dependents = models.IntegerField( default=0, verbose_name="Number of people aged above 60 living with the patient", blank=True) number_of_chronic_diseased_dependents = models.IntegerField( default=0, verbose_name= "Number of people who have chronic diseases living with the patient", blank=True) created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) 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) history = HistoricalRecords(excluded_fields=["patient_search_id"]) objects = SoftDeleteManager() def __str__(self): return "{} - {} - {}".format(self.name, self.age, self.get_gender_display()) @staticmethod def has_write_permission(request): return request.user.is_superuser or request.user.user_type >= User.TYPE_VALUE_MAP[ "Staff"] @staticmethod def has_read_permission(request): return True def has_object_read_permission(self, request): return ( request.user.is_superuser or request.user == self.created_by or (self.facility and request.user == self.facility.created_by) or (request.user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"] and request.user.district == self.district)) def has_object_destroy_permission(self, request): """Currently refers only to delete action""" return request.user.is_superuser def has_object_update_permission(self, request): return ( request.user.is_superuser or request.user == self.created_by or (self.facility and request.user == self.facility.created_by) or (request.user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"] and request.user.district == self.district) # TODO State Level Permissions ) @property def tele_consultation_history(self): return self.patientteleconsultation_set.order_by("-id") def save(self, *args, **kwargs) -> None: """ While saving, if the local body is not null, then district will be local body's district Overriding save will help in a collision where the local body's district and district fields are different. It also creates/updates the PatientSearch model Parameters ---------- args: list of args - not used kwargs: keyword args - not used Returns ------- None """ if self.local_body is not None: self.district = self.local_body.district if self.district is not 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) is_create = self.pk is None super().save(*args, **kwargs) if is_create or self.patient_search_id is None: ps = PatientSearch.objects.create( 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, ) self.patient_search_id = ps.pk self.save() else: PatientSearch.objects.filter(pk=self.patient_search_id).update( 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, )
class PatientRegistration(PatientBaseModel, PatientPermissionMixin): # fields in the PatientSearch model PATIENT_SEARCH_KEYS = ["name", "gender", "phone_number", "date_of_birth", "year_of_birth", "state_id"] class SourceEnum(enum.Enum): CARE = 10 COVID_TRACKER = 20 STAY = 30 SourceChoices = [(e.value, e.name) for e in SourceEnum] source = models.IntegerField(choices=SourceChoices, default=SourceEnum.CARE.value) facility = models.ForeignKey("Facility", on_delete=models.SET_NULL, null=True) nearest_facility = models.ForeignKey( "Facility", on_delete=models.SET_NULL, null=True, related_name="nearest_facility" ) meta_info = models.OneToOneField("PatientMetaInfo", on_delete=models.SET_NULL, null=True) name = EncryptedCharField(max_length=200) age = models.PositiveIntegerField(null=True, blank=True) gender = models.IntegerField(choices=GENDER_CHOICES, blank=False) phone_number = EncryptedCharField(max_length=14, validators=[phone_number_regex]) address = EncryptedTextField(default="") 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") 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=True, max_length=4, 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(null=True, blank=True) past_travel = models.BooleanField( default=False, verbose_name="Travelled to Any Foreign Countries in the last 28 Days", ) countries_travelled_old = models.TextField( null=True, blank=True, verbose_name="Countries Patient has Travelled to", editable=False ) 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" ) 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") 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) disease_status = models.IntegerField( choices=DISEASE_STATUS_CHOICES, default=1, blank=True, verbose_name="Disease Status" ) number_of_aged_dependents = models.IntegerField( default=0, verbose_name="Number of people aged above 60 living with the patient", blank=True ) number_of_chronic_diseased_dependents = models.IntegerField( default=0, verbose_name="Number of people who have chronic diseases living with the patient", blank=True ) created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) 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) date_of_receipt_of_information = models.DateTimeField( null=True, blank=True, verbose_name="Patient's information received date" ) history = HistoricalRecords(excluded_fields=["patient_search_id", "meta_info"]) objects = BaseManager() def __str__(self): return "{} - {} - {}".format(self.name, self.age, self.get_gender_display()) @property def tele_consultation_history(self): return self.patientteleconsultation_set.order_by("-id") def save(self, *args, **kwargs) -> None: """ While saving, if the local body is not null, then district will be local body's district Overriding save will help in a collision where the local body's district and district fields are different. It also creates/updates the PatientSearch model Parameters ---------- args: list of args - not used kwargs: keyword args - not used Returns ------- None """ if self.local_body is not None: self.district = self.local_body.district if self.district is not 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_receipt_of_information = ( self.date_of_receipt_of_information if self.date_of_receipt_of_information is not None else datetime.datetime.now() ) is_create = self.pk is None super().save(*args, **kwargs) if is_create or self.patient_search_id is None: ps = PatientSearch.objects.create( 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, ) self.patient_search_id = ps.pk self.save() else: PatientSearch.objects.filter(pk=self.patient_search_id).update( 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, )