this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat:added primary_encounter in account datapoint and modified account,encounter datapoint structure (#3535)

* feat:added primary_encounter and modified encounter datapoint structure

* few changes to account datapoints

* feat:added some account fields

authored by

Nandkishor R and committed by
GitHub
1dbdc659 0d866d35

+170 -69
+26 -7
care/emr/reports/context_builder/data_points/account.py
··· 5 5 SingleObjectContextBuilder, 6 6 ) 7 7 from care.emr.reports.context_builder.data_points.charge_items import ( 8 - AccountChargeItemCategoryContextBuilder, 8 + AccountChargeItemCategorySummaryContextBuilder, 9 9 AccountChargeItemContextBuilder, 10 + ) 11 + from care.emr.reports.context_builder.data_points.encounter import ( 12 + MinimumEncounterReportContext, 10 13 ) 11 14 from care.emr.reports.context_builder.data_points.facility import FacilityContextBuilder 12 15 from care.emr.reports.context_builder.data_points.invoice import ( ··· 40 43 41 44 42 45 class BaseAccountContextBuilder(SingleObjectContextBuilder): 46 + external_id = Field( 47 + display="Account External ID", 48 + preview_value="beff3ce1-e1be-41bc-8fb9-07ce2ebe42a6", 49 + description="Unique identifier for the account", 50 + ) 43 51 name = Field( 44 52 display="Account Title", 45 53 preview_value="General Checkup Account", ··· 70 78 ) 71 79 total_gross = Field( 72 80 display="Total Gross Amount", 73 - preview_value="180.00", 81 + preview_value="180.000000", 74 82 description="Total gross amount for the account", 75 83 ) 76 84 total_paid = Field( 77 85 display="Total Paid Amount", 78 - preview_value="100.00", 86 + preview_value="100.000000", 79 87 description="Total amount paid towards the account", 80 88 ) 81 89 total_balance = Field( 82 90 display="Total Balance Amount", 83 - preview_value="80.00", 91 + preview_value="80.000000", 84 92 description="Total balance amount remaining for the account", 85 93 ) 94 + total_billable_charge_items = Field( 95 + display="Total Billable Charge Items", 96 + preview_value="1455.000000", 97 + description="Total number of billable charge items associated with the account", 98 + ) 86 99 total_price_components = Field( 87 100 display="Total Price Components", 88 101 preview_value="", ··· 101 114 target_context=AccountChargeItemContextBuilder, 102 115 description="Chargeable items associated with the account", 103 116 ) 104 - category_charge_items = Field( 105 - display="Category-wise Charge Items", 117 + category_charge_items_summary = Field( 118 + display="Charge Items Category Summary", 106 119 preview_value="", 107 - target_context=AccountChargeItemCategoryContextBuilder, 120 + target_context=AccountChargeItemCategorySummaryContextBuilder, 108 121 description="Charge items categorized by their types for the account", 109 122 ) 110 123 payment_reconciliations = Field( ··· 122 135 display="Account Calculated At", 123 136 preview_value="2023-01-20T15:45:00Z", 124 137 description="Date when the account totals were last calculated", 138 + ) 139 + primary_encounter = Field( 140 + display="Primary Encounter", 141 + preview_value="", 142 + target_context=MinimumEncounterReportContext, 143 + description="Primary encounter associated with the account", 125 144 ) 126 145 127 146
+43 -7
care/emr/reports/context_builder/data_points/charge_items.py
··· 1 1 from decimal import Decimal 2 2 3 - from django.db.models import Sum 3 + from django.db.models import Q, Sum 4 4 from django_filters import rest_framework as filters 5 5 6 6 from care.emr.models.charge_item import ChargeItem ··· 8 8 from care.emr.reports.context_builder.data_points.base import ( 9 9 Field, 10 10 QuerysetContextBuilder, 11 + SingleObjectContextBuilder, 11 12 ) 12 13 from care.emr.reports.context_builder.data_points.invoice import ( 13 14 ChargeItemInvoiceContextBuilder, ··· 130 131 131 132 132 133 class AccountChargeItemCategoryContextBuilder(QuerysetContextBuilder): 133 - def get_category_charge_items_summary(self, account): 134 + def get_category_charge_items_summary(self, account, is_refund=False): 134 135 categories = ResourceCategory.objects.filter( 135 136 resource_type="charge_item_definition", 136 137 facility_id=self.parent_context.facility_id, ··· 138 139 ) 139 140 summary = [] 140 141 for category in categories: 141 - charge_items = ChargeItem.objects.filter( 142 - account_id=account.id, 143 - charge_item_definition__category=category, 144 - status__in=ACTIVE_CHARGE_ITEM_STATUSES, 145 - ) 142 + if is_refund: 143 + charge_items = ChargeItem.objects.filter( 144 + account_id=account.id, 145 + charge_item_definition__category=category, 146 + status__in=ACTIVE_CHARGE_ITEM_STATUSES, 147 + paid_invoice__is_refund=True, 148 + ) 149 + else: 150 + charge_items = ChargeItem.objects.filter( 151 + account_id=account.id, 152 + charge_item_definition__category=category, 153 + status__in=ACTIVE_CHARGE_ITEM_STATUSES, 154 + ).filter( 155 + Q(paid_invoice__isnull=True) | Q(paid_invoice__is_refund=False) 156 + ) 146 157 if not charge_items.exists(): 147 158 continue 148 159 paid_charge_items = charge_items.filter( ··· 227 238 else "0.00", 228 239 description="Total billed price of charge items in this category", 229 240 ) 241 + 242 + 243 + class AccountReturnedChargeItemCategoryContextBuilder( 244 + AccountChargeItemCategoryContextBuilder 245 + ): 246 + def get_context(self): 247 + return self.get_category_charge_items_summary( 248 + self.parent_context, is_refund=True 249 + ) 250 + 251 + 252 + class AccountChargeItemCategorySummaryContextBuilder(SingleObjectContextBuilder): 253 + category_charge_items = Field( 254 + display="Category Charge Items", 255 + preview_value="", 256 + target_context=AccountChargeItemCategoryContextBuilder, 257 + description="Charge items under this category", 258 + ) 259 + 260 + category_returned_charge_items = Field( 261 + display="Category Returned Charge Items", 262 + preview_value="", 263 + target_context=AccountReturnedChargeItemCategoryContextBuilder, 264 + description="Returned charge items under this category", 265 + )
+101 -55
care/emr/reports/context_builder/data_points/encounter.py
··· 1 1 from types import SimpleNamespace 2 2 3 - from care.emr.models.encounter import Encounter 3 + from care.emr.models.encounter import Encounter, EncounterOrganization 4 4 from care.emr.reports.context_builder.data_point_registry import DataPointRegistry 5 5 from care.emr.reports.context_builder.data_points.allergy_intolerance import ( 6 6 AllergyIntoleranceContextBuilder, ··· 37 37 "entered_in_error": "Entered in Error", 38 38 } 39 39 40 + ENCOUNTER_CLASS_DISPLAY = { 41 + "imp": "Inpatient", 42 + "amb": "Outpatient", 43 + "obsenc": "Observation", 44 + "emer": "Emergency", 45 + "vr": "Virtual", 46 + "hh": "Home Health", 47 + } 48 + 40 49 41 50 class EncounterCareTeamContextBuilder(QuerysetContextBuilder): 42 51 def get_context(self): ··· 77 86 ) 78 87 79 88 80 - class EncounterReportContextBase(SingleObjectContextBuilder): 81 - standalone_context = True 82 - __slug__ = "encounter_base" 83 - __associating_model__ = Encounter 84 - __display_name__ = "Encounter Report" 85 - __description__ = "Report context for encounter-based reports" 86 - context_key = "encounter" 89 + class EncounterOrganizationsContextBuilder(QuerysetContextBuilder): 90 + def get_context(self): 91 + return EncounterOrganization.objects.filter(encounter_id=self.parent_context.id) 92 + 93 + organization = Field( 94 + display="Organization", 95 + preview_value="", 96 + mapping=lambda o: o.organization.name if o.organization else "", 97 + description="Organization associated with the encounter", 98 + ) 99 + 87 100 101 + class BaseEncounterReportContext(SingleObjectContextBuilder): 88 102 status = Field( 89 103 display="Encounter Status", 90 104 mapping=lambda e: STATUS_DISPLAY.get( ··· 93 107 preview_value="In Progress", 94 108 description="Current status of the encounter", 95 109 ) 96 - symptoms = Field( 97 - target_context=SymptomsContextBuilder, 98 - display="Symptoms", 99 - preview_value="", 100 - description="Symptoms of the encounter", 101 - ) 102 - allergy_intolerances = Field( 103 - target_context=AllergyIntoleranceContextBuilder, 104 - display="Allergy Intolerances", 105 - preview_value="", 106 - description="Allergy intolerances of the encounter", 107 - ) 108 - diagnoses = Field( 109 - target_context=DiagnosisContextBuilder, 110 - display="Diagnoses", 111 - preview_value="", 112 - description="Diagnoses of the encounter", 110 + 111 + encounter_class = Field( 112 + display="Encounter Class", 113 + mapping=lambda e: ENCOUNTER_CLASS_DISPLAY.get( 114 + e.encounter_class, e.encounter_class.title() if e.encounter_class else "" 115 + ), 116 + preview_value="Outpatient", 117 + description="Classification of the encounter", 113 118 ) 114 119 care_team = Field( 115 120 target_context=EncounterCareTeamContextBuilder, ··· 117 122 preview_value="", 118 123 description="Care team of the encounter", 119 124 ) 120 - questionnaire_responses = Field( 121 - target_context=QuestionnaireContextBuilder, 122 - display="Questionnaire Responses", 125 + 126 + current_location = Field( 127 + display="Current Location", 128 + target_context=EncounterFacilityLocationContextBuilder, 123 129 preview_value="", 124 - description="Questionnaire responses of the encounter", 130 + description="Current location within the facility for the encounter", 125 131 ) 126 132 127 - medication_prescriptions = Field( 128 - display="Medication Prescriptions", 129 - target_context=MedicationPrescriptionContextBuilder, 133 + start_time = Field( 134 + display="Encounter Start Time", 135 + mapping=lambda e: e.period.get("start") if e.period else None, 136 + preview_value="2026-01-12T10:01:45.088000Z", 137 + description="Start time of the encounter", 138 + ) 139 + end_time = Field( 140 + display="Encounter End Time", 141 + mapping=lambda e: e.period.get("end") 142 + if e.period and e.period.get("end") 143 + else "Ongoing", 144 + preview_value="2026-01-12T10:01:45.088000Z", 145 + description="End time of the encounter", 146 + ) 147 + organizations = Field( 148 + display="Associated Organizations", 149 + target_context=EncounterOrganizationsContextBuilder, 130 150 preview_value="", 131 - description="Medication prescriptions of the encounter", 151 + description="Organizations associated with the encounter", 132 152 ) 153 + 154 + 155 + class MinimumEncounterReportContext(BaseEncounterReportContext): 156 + def get_context(self): 157 + return getattr(self.parent_context, self.parent_attribute) 158 + 159 + 160 + class EncounterReportContext(BaseEncounterReportContext): 161 + standalone_context = True 162 + __slug__ = "encounter_base" 163 + __associating_model__ = Encounter 164 + __display_name__ = "Encounter Report" 165 + __description__ = "Report context for encounter-based reports" 166 + context_key = "encounter" 167 + 133 168 patient = Field( 134 169 display="Patient Details", 135 170 target_context=PatientMinimumContextBuilder, 136 171 preview_value="", 137 172 description="Details of the patient associated with the encounter", 173 + ) 174 + 175 + facility = Field( 176 + display="Facility Details", 177 + target_context=FacilityContextBuilder, 178 + preview_value="", 179 + description="Details of the facility where the encounter took place", 138 180 ) 139 181 140 182 diagnostic_reports = Field( ··· 143 185 description="Diagnostic reports associated with the encounter", 144 186 target_context=DiagnosticReportContextBuilder, 145 187 ) 146 - 147 - facility = Field( 148 - display="Facility Details", 149 - target_context=FacilityContextBuilder, 188 + symptoms = Field( 189 + target_context=SymptomsContextBuilder, 190 + display="Symptoms", 150 191 preview_value="", 151 - description="Details of the facility where the encounter took place", 192 + description="Symptoms of the encounter", 152 193 ) 153 - current_location = Field( 154 - display="Current Location", 155 - target_context=EncounterFacilityLocationContextBuilder, 194 + allergy_intolerances = Field( 195 + target_context=AllergyIntoleranceContextBuilder, 196 + display="Allergy Intolerances", 156 197 preview_value="", 157 - description="Current location within the facility for the encounter", 198 + description="Allergy intolerances of the encounter", 199 + ) 200 + diagnoses = Field( 201 + target_context=DiagnosisContextBuilder, 202 + display="Diagnoses", 203 + preview_value="", 204 + description="Diagnoses of the encounter", 158 205 ) 159 206 160 - start_time = Field( 161 - display="Encounter Start Time", 162 - mapping=lambda e: e.period.get("start") if e.period else None, 163 - preview_value="2026-01-12T10:01:45.088000Z", 164 - description="Start time of the encounter", 207 + questionnaire_responses = Field( 208 + target_context=QuestionnaireContextBuilder, 209 + display="Questionnaire Responses", 210 + preview_value="", 211 + description="Questionnaire responses of the encounter", 165 212 ) 166 - end_time = Field( 167 - display="Encounter End Time", 168 - mapping=lambda e: e.period.get("end") 169 - if e.period and e.period.get("end") 170 - else "Ongoing", 171 - preview_value="2026-01-12T10:01:45.088000Z", 172 - description="End time of the encounter", 213 + 214 + medication_prescriptions = Field( 215 + display="Medication Prescriptions", 216 + target_context=MedicationPrescriptionContextBuilder, 217 + preview_value="", 218 + description="Medication prescriptions of the encounter", 173 219 ) 174 220 175 221 176 - DataPointRegistry.register(EncounterReportContextBase) 222 + DataPointRegistry.register(EncounterReportContext)