99 Concept ,
1010 CustomFilter ,
1111 GroupSubject ,
12- } from "avni-models" ;
12+ ObservationsHolder
13+ } from "openchs-models" ;
1314import General from "../utility/General" ;
1415import _ from "lodash" ;
1516import ConceptService from "./ConceptService" ;
@@ -118,7 +119,7 @@ class CustomFilterService extends BaseService {
118119
119120 // Note that the query is run for every filter(concept) separately, this is because we don't have
120121 // joins in realm and after getting latest from each filter(concept) we need to query for selected concept answer.
121- queryFromLatestObservation ( schemaName , conceptFilters , selectedAnswerFilters , scopeFilters , sortFilter , indFunc , widget ) {
122+ queryFromLatestObservation ( schemaName , conceptFilters , selectedAnswerFilters , scopeFilters , sortFilter , indFunc , widget , inMemoryFilter ) {
122123 const latestEncounters = this . db . objects ( schemaName )
123124 . filtered ( `voided = false ` )
124125 //limit the scope of query by giving encounter/program uuid
@@ -129,15 +130,16 @@ class CustomFilterService extends BaseService {
129130 . filtered ( _ . isEmpty ( sortFilter ) ? 'uuid != null' : ` ${ sortFilter } ` ) ;
130131
131132 return widget === CustomFilter . widget . Range ? this . filterForRangeWidgetType ( latestEncounters , selectedAnswerFilters , indFunc )
132- : this . filterForFixedWidgetType ( latestEncounters , schemaName , selectedAnswerFilters , indFunc ) ;
133+ : this . filterForFixedWidgetType ( latestEncounters , schemaName , selectedAnswerFilters , indFunc , inMemoryFilter ) ;
133134 }
134135
135- filterForFixedWidgetType ( latestEncounters , schemaName , selectedAnswerFilters , indFunc ) {
136+ filterForFixedWidgetType ( latestEncounters , schemaName , selectedAnswerFilters , indFunc , inMemoryFilter ) {
136137 //cannot append next filtered to this query because sorting happens at the end of query and we will not get expected result.
137138 //so we get the most recent encounters from above query and pass it down to the next query.
138139 return _ . isEmpty ( latestEncounters ) ? [ ] : [ ...latestEncounters
139140 //check if selected filter is present in the observations
140141 . filtered ( ` ${ selectedAnswerFilters ( ) } ` )
142+ . filterInternal ( ( obsHolder ) => inMemoryFilter ( obsHolder ) )
141143 . map ( indFunc )
142144 ] ;
143145 }
@@ -190,8 +192,8 @@ class CustomFilterService extends BaseService {
190192 const selectedOption = _ . head ( selectedOptions ) ;
191193 switch ( concept . datatype ) {
192194 case ( Concept . dataType . Coded ) :
193- const codedFilterQuery = _ . map ( selectedOptions , c => ` (concept.uuid == '${ concept . uuid } ' AND valueJSON CONTAINS[c] '${ c . uuid } ') ` ) . join ( " OR " ) ;
194- return ( ) => this . getObsSubQueryForQuery ( codedFilterQuery ) ;
195+ const codedFilterQuery = _ . map ( selectedOptions , c => ` (observations. concept.uuid == '${ concept . uuid } ' AND observations. valueJSON CONTAINS[c] '${ c . uuid } ') ` ) . join ( " OR " ) ;
196+ return ( ) => codedFilterQuery ;
195197 case ( Concept . dataType . Text ) :
196198 case ( Concept . dataType . Notes ) :
197199 case ( Concept . dataType . Id ) :
@@ -239,15 +241,15 @@ class CustomFilterService extends BaseService {
239241 return filter . join ( " AND " ) ;
240242 }
241243
242- queryConceptTypeFilters ( scope , scopeParameters , selectedAnswerFilters , conceptFilter , widget ) {
244+ queryConceptTypeFilters ( scope , scopeParameters , selectedAnswerFilters , conceptFilter , widget , inMemoryFilter ) {
243245 switch ( scope ) {
244246 case CustomFilter . scope . ProgramEncounter : {
245247 const encounterOptions = _ . map ( scopeParameters . encounterTypeUUIDs , e => `encounterType.uuid == "${ e } "` ) . join ( " OR " ) ;
246248 const programOptions = _ . map ( scopeParameters . programUUIDs , p => `programEnrolment.program.uuid == "${ p } "` ) . join ( " OR " ) ;
247249 const scopeFilters = this . createProgramEncounterScopeFilter ( encounterOptions , programOptions ) ;
248250 const scopeFiltersWithNonExit = `(${ scopeFilters } ) and programEnrolment.programExitDateTime = null` ;
249251 const sortFilter = 'TRUEPREDICATE sort(programEnrolment.individual.uuid asc , encounterDateTime desc) Distinct(programEnrolment.individual.uuid)' ;
250- const individualUUIDs = this . queryFromLatestObservation ( ProgramEncounter . schema . name , conceptFilter , selectedAnswerFilters , scopeFiltersWithNonExit , sortFilter , enc => enc . programEnrolment . individual . uuid , widget ) ;
252+ const individualUUIDs = this . queryFromLatestObservation ( ProgramEncounter . schema . name , conceptFilter , selectedAnswerFilters , scopeFiltersWithNonExit , sortFilter , enc => enc . programEnrolment . individual . uuid , widget , inMemoryFilter ) ;
251253 this . updateIndividuals ( individualUUIDs ) ;
252254 break ;
253255 }
@@ -256,20 +258,20 @@ class CustomFilterService extends BaseService {
256258 const scopeFilters = this . createProgramEncounterScopeFilter ( null , programOptions ) ;
257259 const scopeFiltersWithNonExit = `(${ scopeFilters } ) and programExitDateTime = null` ;
258260 const sortFilter = 'TRUEPREDICATE sort(individual.uuid asc , enrolmentDateTime desc) Distinct(individual.uuid)' ;
259- const individualUUIDs = this . queryFromLatestObservation ( ProgramEnrolment . schema . name , conceptFilter , selectedAnswerFilters , scopeFiltersWithNonExit , sortFilter , enl => enl . individual . uuid , widget ) ;
261+ const individualUUIDs = this . queryFromLatestObservation ( ProgramEnrolment . schema . name , conceptFilter , selectedAnswerFilters , scopeFiltersWithNonExit , sortFilter , enl => enl . individual . uuid , widget , inMemoryFilter ) ;
260262 this . updateIndividuals ( individualUUIDs ) ;
261263 break ;
262264 }
263265 case CustomFilter . scope . Registration : {
264- const individualUUIDs = this . queryFromLatestObservation ( Individual . schema . name , null , selectedAnswerFilters , null , null , ind => ind . uuid , widget ) ;
266+ const individualUUIDs = this . queryFromLatestObservation ( Individual . schema . name , null , selectedAnswerFilters , null , null , ind => ind . uuid , widget , inMemoryFilter ) ;
265267 this . updateIndividuals ( individualUUIDs ) ;
266268 break ;
267269 }
268270 case CustomFilter . scope . Encounter : {
269271 const encounterOptions = _ . map ( scopeParameters . encounterTypeUUIDs , e => `encounterType.uuid == "${ e } "` ) . join ( " OR " ) ;
270272 const scopeFilters = this . createProgramEncounterScopeFilter ( encounterOptions , null ) ;
271273 const sortFilter = 'TRUEPREDICATE sort(individual.uuid asc , encounterDateTime desc) Distinct(individual.uuid)' ;
272- const individualUUIDs = this . queryFromLatestObservation ( Encounter . schema . name , conceptFilter , selectedAnswerFilters , scopeFilters , sortFilter , enc => enc . individual . uuid , widget ) ;
274+ const individualUUIDs = this . queryFromLatestObservation ( Encounter . schema . name , conceptFilter , selectedAnswerFilters , scopeFilters , sortFilter , enc => enc . individual . uuid , widget , inMemoryFilter ) ;
273275 this . updateIndividuals ( individualUUIDs ) ;
274276 break ;
275277 }
@@ -292,7 +294,10 @@ class CustomFilterService extends BaseService {
292294 const conceptFilter = `observations.concept.uuid == "${ conceptUUID } "` ;
293295 switch ( type ) {
294296 case CustomFilter . type . Concept :
295- this . queryConceptTypeFilters ( scope , scopeParameters , selectedAnswerFilterQuery , conceptFilter , widget ) ;
297+ const concept = this . getService ( ConceptService ) . findByUUID ( conceptUUID ) ;
298+ const inMemoryFilter = concept . isCodedConcept ( ) ?
299+ ( obsHolder ) => ObservationsHolder . hasAnyAnswer ( obsHolder , conceptUUID , selectedOptions . map ( x => x . uuid ) , ) : null ;
300+ this . queryConceptTypeFilters ( scope , scopeParameters , selectedAnswerFilterQuery , conceptFilter , widget , inMemoryFilter ) ;
296301 break ;
297302 case CustomFilter . type . RegistrationDate :
298303 this . updateIndividuals ( this . queryEntity ( Individual . schema . name , selectedAnswerFilterQuery , null , ind => ind . uuid ) ) ;
0 commit comments