app/assets/javascripts/patient_api_extension.js.coffee in hqmf2js-1.2.1 vs app/assets/javascripts/patient_api_extension.js.coffee in hqmf2js-1.3.0
- old
+ new
@@ -5,10 +5,42 @@
hQuery.Patient::allProblems = -> this.conditions().concat(this.socialHistories()).concat(this.procedures())
hQuery.Patient::allDevices = -> this.conditions().concat(this.procedures()).concat(this.careGoals()).concat(this.medicalEquipment())
hQuery.Patient::activeDiagnoses = -> this.conditions().concat(this.socialHistories()).withStatuses(['active'])
hQuery.Patient::inactiveDiagnoses = -> this.conditions().concat(this.socialHistories()).withStatuses(['inactive'])
hQuery.Patient::resolvedDiagnoses = -> this.conditions().concat(this.socialHistories()).withStatuses(['resolved'])
+
+hQuery.Patient::getAndCacheEvents = (key, that, fn, args...) ->
+ this.cache ||= {}
+ if !this.cache[key]
+ this.cache[key] = fn.apply(that, args)
+ this.cache[key]
+hQuery.Patient::getEvents = (eventCriteria) ->
+ cacheKey = eventCriteria.type
+ events = this.getAndCacheEvents(cacheKey, this, this[eventCriteria.type])
+ if eventCriteria.statuses && eventCriteria.statuses.length > 0
+ cacheKey = cacheKey + "_" + String(eventCriteria.statuses)
+ events = this.getAndCacheEvents(cacheKey, events, events.withStatuses, eventCriteria.statuses, eventCriteria.includeEventsWithoutStatus)
+ cacheKey = cacheKey + "_" + String(eventCriteria.negated) + String(eventCriteria.negationValueSetId)
+ if eventCriteria.negated
+ codes = getCodes(eventCriteria.negationValueSetId)
+ events = this.getAndCacheEvents(cacheKey, events, events.withNegation, codes)
+ else
+ events = this.getAndCacheEvents(cacheKey, events, events.withoutNegation)
+ if eventCriteria.valueSetId
+ cacheKey = cacheKey + "_" + String(eventCriteria.valueSetId) + "_" + String(eventCriteria.start) + "_" + String(eventCriteria.stop)
+ codes = getCodes(eventCriteria.valueSetId)
+ events = this.getAndCacheEvents(cacheKey, events, events.match, codes, eventCriteria.start, eventCriteria.stop, true)
+ else if eventCriteria.valueSet
+ events = events.match(eventCriteria.valueSet, eventCriteria.start, eventCriteria.stop, true)
+ events = events.slice(0) # clone cached array before we add on specific occurrence
+ if eventCriteria.specificOccurrence
+ events.specific_occurrence = eventCriteria.specificOccurrence
+ events
+
+hQuery.Patient::deathdate = ->
+ hQuery.dateFromUtcSeconds this.json["deathdate"]
+
hQuery.CodedEntry::asIVL_TS = ->
tsLow = new TS()
tsLow.date = this.startDate() || this.date() || null
tsHigh = new TS()
tsHigh.date = this.endDate() || this.date() || null
@@ -19,9 +51,62 @@
ts
hQuery.Encounter::lengthOfStay = (unit) ->
ivl_ts = this.asIVL_TS()
ivl_ts.low.difference(ivl_ts.high, unit)
+
+hQuery.AdministrationTiming::dosesPerDay = () ->
+ #figure out the units and value and calculate
+ p = this.period()
+ switch(p.unit())
+ when "h"
+ 24/p.value()
+ when "d"
+ 1/p.value()
+
+
+hQuery.Fulfillment::daysInRange = (dateRange,doesPerDay) ->
+ # this will give us the number of days this fullfilment was for
+ totalDays = this.quantityDispensed().value()/doesPerDay
+ totalDays = 0 if isNaN(totalDays)
+ endDate = new Date(this.dispenseDate().getTime() + (totalDays*60*60*24*1000))
+ high = if dateRange && dateRange.high then dateRange.high.asDate() else endDate
+ low = if dateRange && dateRange.low then dateRange.low.asDate() else this.dispenseDate()
+ # from the date it was deispensed add the total number of days to
+ # get the end date of the fullfillment. Note that this may not
+ # be the actual number of days the person took the meds but the
+ # measure developers and the guidance given around CMD have not been
+ # thought out very well at all. For reporting this should really just
+ # be done based off of start and end dates and not any sort of tallying of
+ # doses.
+ startDiff = TS.daysDifference(low,this.dispenseDate())
+ endDiff = TS.daysDifference(endDate,high)
+ # startDiff will be - if the start date was before the date range
+ # so we can trim those first days off the total
+ totalDays += startDiff if startDiff < 0
+ #endDiff will be negative if the end date was after the rage hi value
+ # so we can trim those days off
+ totalDays += endDiff if endDiff < 0
+ #if we have a negative value set it to zero
+ totalDays = 0 if isNaN(totalDays) || totalDays < 0
+ totalDays
+
+# Determin sum the cmd for each fullFillment history based on the
+# date range
+hQuery.Medication::fulfillmentTotals = (dateRange)->
+ dpd = this.administrationTiming().dosesPerDay()
+ this.fulfillmentHistory().reduce (t, s) ->
+ t + s.daysInRange(dateRange,dpd)
+ , 0
+
+hQuery.Medication::cumulativeMedicationDuration = (dateRange) ->
+ #assuming that the dose is the same across fills and that fills is stated in individual
+ #doses not total amount. Will need to flush this out more at a later point in time.
+ #Considering that liquid meds are probaly dispensed as total volume ex 325ml with a dose of
+ #say 25ml per dose. Will definatley need to revisit this.
+ this.fulfillmentTotals(dateRange) if this.administrationTiming()
+
+
hQuery.CodedEntry::respondTo = (functionName) ->
typeof(@[functionName]) == "function"
hQuery.CodedEntryList::isTrue = ->