def get_address_struct(self, row: DataFrame) -> Optional[AddressStruct]: return AddressStruct(address1=row_value(row, self.address_line_1, ''), address2='', city=row_value(row, self.city, ''), state=row_value(row, self.state, ''), zip=row_value(row, self.zip, ''), phone_number=row_value(row, self.phone, ''))
def get_drug_struct(self, row: DataFrame) -> DrugStruct: return DrugStruct(ndc=row[self.ndc], drug_name=row_value(row, self.drug_name, "-"), brand_flag=row_value(row, self.generic_indicator, "-"), gpi="-", gcn="-")
def get_provider_struct(self, row: DataFrame) -> Optional[ProviderStruct]: npi = self.get_npi(row) if not npi: return None mg_struct = self.get_medical_group_struct(row) return ProviderStruct(first_name=row_value(row, self.first_name), last_name=row_value(row, self.last_name), npi=npi, medical_group=mg_struct)
def get_medical_group_struct( self, row: DataFrame) -> Optional[MedicalGroupStruct]: tin = row_value(row, self.tin) if not tin: return None address_struct = self.get_address_struct(row) return MedicalGroupStruct(name=row_value(row, self.practice_name, f"- ({tin})"), tin=tin, address=address_struct)
def get_adt_event_struct(self, row: DataFrame) -> Optional[AdtEventStruct]: try: event_days = int(row_value(row, self.event_days, 0)) except ValueError: # If the value that's in the file fails to parse, save this as zero. event_days = 0 event_struct = AdtEventStruct( first_name=row[self.first_name], last_name=row[self.last_name], date_of_birth=row[self.date_of_birth], facility_name=row[self.facility_name], facility_type=row[self.facility_type], event_type=row_value(row, self.event_type), event_date=row_value(row, self.event_date), event_days=event_days, diagnosis_codes=row[self.diagnosis_codes] | [], ) return event_struct
def get_drug_fill_struct(self, row: DataFrame) -> DrugFillStruct: refills_authorized = self.get_refills_authorized(row) drug_struct = self.get_drug_struct(row) return DrugFillStruct( claim_number=row[self.claim_number], member_number=row[self.member_number], ndc=row[self.ndc], drug=drug_struct, # When we don't use row_value, it means that we expect these values to # always be present, and always have an expected format. refill_number=Decimal(row_value(row, self.refill_number, default=0)).to_integral_value(), quantity_dispensed=Decimal( row[self.quantity_dispensed]).to_integral_value(), days_supply=Decimal(row[self.days_supply]).to_integral_value(), refills_authorized=refills_authorized, script_written_date=row_value(row, self.script_written_date, None), fill_date=row_value(row, self.fill_date, None))
def get_refills_authorized(self, row: DataFrame) -> Optional[int]: # If this value is set in the ETL, then use it and pull out the number of # refills authorized. refills_authorized = None if self.refills_authorized: n = row_value(row, self.refills_authorized, na_values=self.NA_VALUES) if n: refills_authorized = Decimal(n).to_integral_value() return refills_authorized
def get_claim_struct(self, row: DataFrame, claim_cls: Type[ClaimStruct] = ClaimStruct ) -> Optional[ClaimStruct]: drug_fill_struct = self.get_drug_fill_struct(row) ap_raw_value = row_value(row, self.amount_paid, '0', self.NA_VALUES) amount_paid = Decimal(ap_raw_value) ag_raw_value = row_value(row, self.amount_gross, '0', self.NA_VALUES) amount_gross = Decimal(ag_raw_value) claim = claim_cls(claim_number=row[self.claim_number], claim_type=row_value(row, self.claim_type, None) or '', member_number=row[self.member_number], from_date=row[self.from_date], thru_date=row[self.from_date], prescribing_npi=row[self.prescriber_npi], pharmacy_npi=row_value(row, self.pharmacy_npi, None), pharmacy_name=row_value(row, self.pharmacy_name, None), drug_fills=[drug_fill_struct], amount_paid=amount_paid, amount_gross=amount_gross, plan_name=row_value(row, self.plan_name, None)) return claim
def get_patient_struct(self, row: DataFrame) -> PatientStruct: """ A simple extraction of a patient struct from the row. If there is more data to be extracted, mappings that expand from this mapping should override their own methods. """ medical_group = self.get_medical_group_struct(row) provider_struct = self.get_provider_struct(row) # If there is no provider struct, this is an orphan patient. if provider_struct: provider_struct.medical_group = medical_group address_struct = self.get_address_struct(row) return PatientStruct(member_number=row[self.member_number], first_name=row[self.first_name], last_name=row[self.last_name], gender=self.get_gender(row), date_of_birth=row[self.date_of_birth], provider=provider_struct, address=address_struct, line_of_business=row_value( row, self.line_of_business))
def get_address_struct(self, row: DataFrame) -> Optional[AddressStruct]: """ If any of the mappings for an address are set, then an AddressStruct will be created with the data extracted from those columns. Otherwise, this will return None and assume that if addresses are present in the ETL, they will be filled in from somewhere else. """ if not any([ self.address_line_1, self.address_line_2, self.city, self.state, self.zip, self.phone ]): return None return AddressStruct( address1=row_value( row, self.address_line_1, '', na_values=self.NA_VALUES) or '', address2=row_value( row, self.address_line_2, '', na_values=self.NA_VALUES) or '', city=row_value(row, self.city, '', na_values=self.NA_VALUES) or '', state=row_value(row, self.state, '', na_values=self.NA_VALUES) or '', zip=row_value(row, self.zip, '', na_values=self.NA_VALUES) or '', phone_number=row_value( row, self.phone, '', na_values=self.NA_VALUES) or '')
def get_npi(self, row: DataFrame) -> Optional[str]: return row_value(row, self.npi)
def get_appointment_struct( self, row: DataFrame) -> Optional[ExternalAppointmentStruct]: raw_time = row_value(row, self.appointment_time) formatted_time = datetime.strptime(raw_time, "%H%M").time() appointment_timezone = 'America/Boise' appointment_struct = ExternalAppointmentStruct( first_name=row_value(row, self.first_name), last_name=row_value(row, self.last_name), gender=self.get_gender(row), date_of_birth=row_value(row, self.date_of_birth), appointment_date=row_value(row, self.appointment_date), appointment_time=formatted_time, appointment_timezone=appointment_timezone, appointment_type=row_value(row, self.appointment_type), scheduled_provider_npi=row_value(row, self.scheduled_provider_npi), appointment_status=row_value(row, self.appointment_status), member_number=row_value(row, self.member_number), medical_member_number=row_value(row, self.medical_member_number), external_appointment_id=row_value(row, self.external_appointment_id), appointment_location_id=row_value(row, self.appointment_location_id), external_last_modified_date=row_value( row, self.external_last_modified_date), external_created_date=row_value(row, self.external_created_date)) return appointment_struct
def get_claim_struct(self, row: DataFrame, claim_cls: Type[ClaimStruct] = ClaimStruct ) -> Optional[ClaimStruct]: ap_raw_value = row_value(row, self.amount_paid, '0', na_values=self.NA_VALUES) amount_paid = Decimal(ap_raw_value) ag_raw_value = row_value(row, self.amount_gross, '0', na_values=self.NA_VALUES) amount_gross = Decimal(ag_raw_value) claim = claim_cls(claim_number=row[self.claim_number], claim_type=row_value(row, self.claim_type, 'UNK', na_values=self.NA_VALUES), member_number=row[self.member_number], from_date=row_value(row, self.from_date, na_values=self.NA_VALUES), thru_date=row_value(row, self.thru_date, na_values=self.NA_VALUES), admission_date=row_value(row, self.admission_date, na_values=self.NA_VALUES), discharge_date=row_value(row, self.discharge_date, na_values=self.NA_VALUES), provider_npi=row_value(row, self.provider_npi, na_values=self.NA_VALUES), medical_group_tin=row_value( row, self.medical_group_tin, na_values=self.NA_VALUES), setting=row_value(row, self.setting, na_values=self.NA_VALUES), drg_code=row_value(row, self.drg_code, na_values=self.NA_VALUES), drg_type=row_value(row, self.drg_type, na_values=self.NA_VALUES), amount_paid=amount_paid, amount_gross=amount_gross, revenue_code=row_value(row, self.revenue_code, na_values=self.NA_VALUES), plan_name=row_value(row, self.plan_name, na_values=self.NA_VALUES)) for column in self.procedures: code = row_value(row, column, na_values=self.NA_VALUES) if code: claim.maybe_add_procedure(row[column]) for column in self.diagnoses: code = row_value(row, column, na_values=self.NA_VALUES) if code: claim.maybe_add_diagnosis(row[column]) return claim