11import dayjs from 'dayjs' ;
2- import duration from 'dayjs/plugin/duration' ;
32import customParseFormat from 'dayjs/plugin/customParseFormat' ;
4- dayjs . extend ( duration ) ;
53dayjs . extend ( customParseFormat ) ;
64import findIndex from 'lodash/findIndex' ;
75import filter from 'lodash/filter' ;
@@ -42,11 +40,12 @@ export class CommonExpressionHelpers {
4240 measurementValue : number ,
4341 ) : string | null => {
4442 if ( ! refSectionObject ) {
43+ console . warn ( 'Z-score calculation: No reference data object provided' ) ;
4544 return null ;
4645 }
4746
48- const refObjectValues = Object . keys ( refSectionObject ) . map ( ( key ) => refSectionObject [ key ] ) ;
4947 const refObjectKeys = Object . keys ( refSectionObject ) ;
48+ const refObjectValues = refObjectKeys . map ( ( key ) => refSectionObject [ key ] ) ;
5049 const minimumValue = refObjectValues [ 1 ] ;
5150 const minReferencePoint : number [ ] = [ ] ;
5251
@@ -101,11 +100,8 @@ export class CommonExpressionHelpers {
101100 * @param format - Optional format string for parsing right date (defaults to 'YYYY-MM-DD')
102101 * @returns true if left is before right
103102 */
104- isDateBefore = ( left : Date , right : string | Date , format ?: string ) => {
105- let otherDate : any = right ;
106- if ( typeof right == 'string' ) {
107- otherDate = format ? dayjs ( right , format , true ) . toDate ( ) : dayjs ( right , 'YYYY-MM-DD' , true ) . toDate ( ) ;
108- }
103+ isDateBefore = ( left : Date , right : string | Date , format ?: string ) : boolean => {
104+ const otherDate : Date = right instanceof Date ? right : ( format ? dayjs ( right , format , true ) . toDate ( ) : dayjs ( right , 'YYYY-MM-DD' , true ) . toDate ( ) ) ;
109105 return left ?. getTime ( ) < otherDate . getTime ( ) ;
110106 } ;
111107
@@ -117,7 +113,7 @@ export class CommonExpressionHelpers {
117113 * @param timePeriod - The time unit: 'days', 'weeks', 'months', or 'years'
118114 * @returns true if selectedDate >= (baseDate + duration)
119115 */
120- isDateAfter = ( selectedDate : Date , baseDate : Date , duration : number , timePeriod : string ) => {
116+ isDateAfter = ( selectedDate : Date , baseDate : Date , duration : number , timePeriod : 'days' | 'weeks' | 'months' | 'years' ) : boolean => {
121117 const parsedBaseDate = dayjs ( baseDate ) ;
122118
123119 let calculatedDate : Date ;
@@ -169,43 +165,10 @@ export class CommonExpressionHelpers {
169165 * @returns true if left is after right
170166 */
171167 isDateAfterSimple = ( left : Date , right : string | Date , format ?: string ) : boolean => {
172- let otherDate : Date = right instanceof Date ? right : ( format ? dayjs ( right , format , true ) . toDate ( ) : dayjs ( right , 'YYYY-MM-DD' , true ) . toDate ( ) ) ;
168+ const otherDate : Date = right instanceof Date ? right : ( format ? dayjs ( right , format , true ) . toDate ( ) : dayjs ( right , 'YYYY-MM-DD' , true ) . toDate ( ) ) ;
173169 return left ?. getTime ( ) > otherDate . getTime ( ) ;
174170 } ;
175171
176- /**
177- * Checks if selectedDate is after baseDate plus an offset duration.
178- * This is a more clearly named version of isDateAfter with the same functionality.
179- * @param selectedDate - The date to check
180- * @param baseDate - The base date to add the offset to
181- * @param duration - The number of time units to add
182- * @param timePeriod - The time unit ('days', 'weeks', 'months', or 'years')
183- * @returns true if selectedDate is on or after the calculated date
184- */
185- isDateAfterOffset = ( selectedDate : Date , baseDate : Date , duration : number , timePeriod : 'days' | 'weeks' | 'months' | 'years' ) : boolean => {
186- const parsedBaseDate = dayjs ( baseDate ) ;
187-
188- let calculatedDate : Date ;
189- switch ( timePeriod ) {
190- case 'months' :
191- calculatedDate = parsedBaseDate . add ( duration , 'month' ) . toDate ( ) ;
192- break ;
193- case 'weeks' :
194- calculatedDate = parsedBaseDate . add ( duration , 'week' ) . toDate ( ) ;
195- break ;
196- case 'days' :
197- calculatedDate = parsedBaseDate . add ( duration , 'day' ) . toDate ( ) ;
198- break ;
199- case 'years' :
200- calculatedDate = parsedBaseDate . add ( duration , 'year' ) . toDate ( ) ;
201- break ;
202- default :
203- calculatedDate = new Date ( 0 ) ;
204- }
205-
206- return selectedDate . getTime ( ) >= calculatedDate . getTime ( ) ;
207- } ;
208-
209172 /**
210173 * Retrieves the current value of another form field and registers a dependency.
211174 * When the referenced field changes, expressions using this helper will be re-evaluated.
@@ -320,12 +283,11 @@ export class CommonExpressionHelpers {
320283 * @param arvDispensedInDays - Number of days of ARV medication dispensed
321284 * @returns The next visit date (followupDate + arvDispensedInDays), or null if inputs are missing
322285 */
323- calcNextVisitDate = ( followupDate , arvDispensedInDays ) => {
324- let resultNextVisitDate : Date ;
286+ calcNextVisitDate = ( followupDate : Date , arvDispensedInDays : number ) : Date | null => {
325287 if ( followupDate && arvDispensedInDays ) {
326- resultNextVisitDate = new Date ( followupDate . getTime ( ) + arvDispensedInDays * 24 * 60 * 60 * 1000 ) ;
288+ return new Date ( followupDate . getTime ( ) + arvDispensedInDays * 24 * 60 * 60 * 1000 ) ;
327289 }
328- return resultNextVisitDate ?? null ;
290+ return null ;
329291 } ;
330292
331293 /**
@@ -358,16 +320,10 @@ export class CommonExpressionHelpers {
358320 * @param dateValue - The reference date to calculate age at (defaults to today if not provided)
359321 * @returns Age in years (year difference only, not precise age)
360322 */
361- calcAgeBasedOnDate = ( dateValue ?: ConstructorParameters < typeof Date > [ 0 ] | null ) => {
362- let targetYear = null ;
363- if ( dateValue ) {
364- targetYear = new Date ( dateValue ) . getFullYear ( ) ;
365- } else {
366- targetYear = new Date ( ) . getFullYear ( ) ;
367- }
368- let birthDate = new Date ( this . patient . birthDate ) . getFullYear ( ) ;
369- let calculatedYear = targetYear - birthDate ;
370- return calculatedYear ;
323+ calcAgeBasedOnDate = ( dateValue ?: ConstructorParameters < typeof Date > [ 0 ] | null ) : number => {
324+ const targetYear = dateValue ? new Date ( dateValue ) . getFullYear ( ) : new Date ( ) . getFullYear ( ) ;
325+ const birthYear = new Date ( this . patient . birthDate ) . getFullYear ( ) ;
326+ return targetYear - birthYear ;
371327 } ;
372328
373329 /**
@@ -377,12 +333,11 @@ export class CommonExpressionHelpers {
377333 * @param weight - Weight in kilograms
378334 * @returns BSA in m² rounded to 2 decimal places, or null if inputs are missing
379335 */
380- calcBSA = ( height : number , weight : number ) => {
381- let result : string ;
382- if ( height && weight ) {
383- result = Math . sqrt ( ( height * weight ) / 3600 ) . toFixed ( 2 ) ;
336+ calcBSA = ( height : number , weight : number ) : number | null => {
337+ if ( ! height || ! weight ) {
338+ return null ;
384339 }
385- return result ? parseFloat ( result ) : null ;
340+ return parseFloat ( Math . sqrt ( ( height * weight ) / 3600 ) . toFixed ( 2 ) ) ;
386341 } ;
387342
388343 /**
@@ -496,20 +451,14 @@ export class CommonExpressionHelpers {
496451
497452 /**
498453 * Calculates the gravida (total number of pregnancies) based on term pregnancies and abortions/miscarriages.
499- *
500- * @param {number|string } parityTerm - The number of term pregnancies.
501- * @param {number|string } parityAbortion - The number of abortions (including miscarriages).
502- * @returns {number } The total number of pregnancies (gravida).
503- * @throws {Error } If either input is not a valid number.
504- *
505- * @example
506- * const gravida = calcGravida(2, 1);
507- * console.log(gravida); // Output: 3
454+ * @param parityTerm - The number of term pregnancies (can be number or numeric string)
455+ * @param parityAbortion - The number of abortions including miscarriages (can be number or numeric string)
456+ * @returns The total number of pregnancies (gravida)
457+ * @throws Error if either input is not a valid number
508458 */
509-
510- calcGravida = ( parityTerm , parityAbortion ) => {
511- const term = parseInt ( parityTerm , 10 ) ;
512- const abortion = parseInt ( parityAbortion , 10 ) ;
459+ calcGravida = ( parityTerm : number | string , parityAbortion : number | string ) : number => {
460+ const term = typeof parityTerm === 'number' ? parityTerm : parseInt ( parityTerm , 10 ) ;
461+ const abortion = typeof parityAbortion === 'number' ? parityAbortion : parseInt ( parityAbortion , 10 ) ;
513462
514463 if ( ! Number . isInteger ( term ) || ! Number . isInteger ( abortion ) ) {
515464 throw new Error ( 'Both inputs must be valid numbers.' ) ;
@@ -525,15 +474,15 @@ export class CommonExpressionHelpers {
525474 * @param weight - Patient's weight in kilograms
526475 * @returns Z-score as a string (e.g., '-2', '0', '1'), '-4' if out of range, or null if inputs missing
527476 */
528- calcWeightForHeightZscore = ( height , weight ) => {
477+ calcWeightForHeightZscore = ( height : number , weight : number ) : string | null => {
529478 if ( ! height || ! weight ) {
530479 return null ;
531480 }
532481
533482 const birthDate = new Date ( this . patient . birthDate ) ;
534483 const weightForHeightRef = getZRefByGenderAndAge ( this . patient . sex , birthDate , new Date ( ) ) . weightForHeightRef ;
535484
536- const formattedHeight = parseFloat ( height ) . toFixed ( 1 ) ;
485+ const formattedHeight = height . toFixed ( 1 ) ;
537486 const standardHeightMin = 45 ;
538487 const standardMaxHeight = 110 ;
539488
@@ -556,7 +505,7 @@ export class CommonExpressionHelpers {
556505 * @param weight - Patient's weight in kilograms
557506 * @returns Z-score as a string (e.g., '-2', '0', '1'), or null if inputs missing
558507 */
559- calcBMIForAgeZscore = ( height , weight ) => {
508+ calcBMIForAgeZscore = ( height : number , weight : number ) : string | null => {
560509 if ( ! height || ! weight ) {
561510 return null ;
562511 }
@@ -578,7 +527,7 @@ export class CommonExpressionHelpers {
578527 * @param _weight - Unused parameter kept for backward compatibility
579528 * @returns Z-score as a string (e.g., '-2', '0', '1'), or null if height is missing
580529 */
581- calcHeightForAgeZscore = ( height , _weight ?) => {
530+ calcHeightForAgeZscore = ( height : number , _weight ?: number ) : string | null => {
582531 if ( ! height ) {
583532 return null ;
584533 }
@@ -594,26 +543,24 @@ export class CommonExpressionHelpers {
594543 * Calculates the time difference between an observation date and today.
595544 * @param obsDate - The observation/reference date to compare against today
596545 * @param timeFrame - The unit of time: 'd' (days), 'w' (weeks), 'm' (months), or 'y' (years)
597- * @returns The absolute time difference as a number, or '0' (string) if obsDate is not provided
546+ * @returns The absolute time difference as a number, or 0 if obsDate is not provided
598547 */
599- calcTimeDifference = ( obsDate : Date | dayjs . Dayjs , timeFrame : 'd' | 'w' | 'm' | 'y' ) => {
600- let daySinceLastObs : number | string = '' ;
548+ calcTimeDifference = ( obsDate : Date | dayjs . Dayjs , timeFrame : 'd' | 'w' | 'm' | 'y' ) : number => {
549+ if ( ! obsDate ) {
550+ return 0 ;
551+ }
552+
601553 const endDate = dayjs ( ) ;
602- if ( obsDate ) {
603- if ( timeFrame == 'd' ) {
604- daySinceLastObs = Math . abs ( Math . round ( endDate . diff ( obsDate , 'day' , true ) ) ) ;
605- }
606- if ( timeFrame == 'w' ) {
607- daySinceLastObs = Math . abs ( Math . round ( endDate . diff ( obsDate , 'week' , true ) ) ) ;
608- }
609- if ( timeFrame == 'm' ) {
610- daySinceLastObs = Math . abs ( Math . round ( endDate . diff ( obsDate , 'month' , true ) ) ) ;
611- }
612- if ( timeFrame == 'y' ) {
613- daySinceLastObs = Math . abs ( Math . round ( endDate . diff ( obsDate , 'year' , true ) ) ) ;
614- }
554+ switch ( timeFrame ) {
555+ case 'd' :
556+ return Math . abs ( Math . round ( endDate . diff ( obsDate , 'day' , true ) ) ) ;
557+ case 'w' :
558+ return Math . abs ( Math . round ( endDate . diff ( obsDate , 'week' , true ) ) ) ;
559+ case 'm' :
560+ return Math . abs ( Math . round ( endDate . diff ( obsDate , 'month' , true ) ) ) ;
561+ case 'y' :
562+ return Math . abs ( Math . round ( endDate . diff ( obsDate , 'year' , true ) ) ) ;
615563 }
616- return daySinceLastObs === '' ? '0' : daySinceLastObs ;
617564 } ;
618565
619566 /**
0 commit comments