Skip to content

Commit 5a58398

Browse files
committed
(feat) Expose dayjs for date calculate expressions
1 parent 91afdec commit 5a58398

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

src/utils/common-expression-helpers.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class CommonExpressionHelpers {
2020
allFieldValues: Record<string, any> = {};
2121
api = apiFunctions;
2222
isEmpty = isValueEmpty;
23+
dayjs = dayjs;
2324

2425
constructor(node: FormNode, patient: any, allFields: FormField[], allFieldValues: Record<string, any>) {
2526
this.allFields = allFields;
@@ -101,7 +102,12 @@ export class CommonExpressionHelpers {
101102
* @returns true if left is before right
102103
*/
103104
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());
105+
const otherDate: Date =
106+
right instanceof Date
107+
? right
108+
: format
109+
? dayjs(right, format, true).toDate()
110+
: dayjs(right, 'YYYY-MM-DD', true).toDate();
105111
return left?.getTime() < otherDate.getTime();
106112
};
107113

@@ -113,7 +119,12 @@ export class CommonExpressionHelpers {
113119
* @param timePeriod - The time unit: 'days', 'weeks', 'months', or 'years'
114120
* @returns true if selectedDate >= (baseDate + duration)
115121
*/
116-
isDateAfter = (selectedDate: Date, baseDate: Date, duration: number, timePeriod: 'days' | 'weeks' | 'months' | 'years'): boolean => {
122+
isDateAfter = (
123+
selectedDate: Date,
124+
baseDate: Date,
125+
duration: number,
126+
timePeriod: 'days' | 'weeks' | 'months' | 'years',
127+
): boolean => {
117128
const parsedBaseDate = dayjs(baseDate);
118129

119130
let calculatedDate: Date;
@@ -165,7 +176,12 @@ export class CommonExpressionHelpers {
165176
* @returns true if left is after right
166177
*/
167178
isDateAfterSimple = (left: Date, right: string | Date, format?: string): boolean => {
168-
const otherDate: Date = right instanceof Date ? right : (format ? dayjs(right, format, true).toDate() : dayjs(right, 'YYYY-MM-DD', true).toDate());
179+
const otherDate: Date =
180+
right instanceof Date
181+
? right
182+
: format
183+
? dayjs(right, format, true).toDate()
184+
: dayjs(right, 'YYYY-MM-DD', true).toDate();
169185
return left?.getTime() > otherDate.getTime();
170186
};
171187

src/utils/expression-runner.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,24 @@ export const testFields: Array<FormField> = [
7676
},
7777
id: 'bodyTemperature',
7878
},
79+
{
80+
label: 'Date of Birth',
81+
type: 'obs',
82+
questionOptions: {
83+
rendering: 'date',
84+
concept: 'date_of_birth_concept',
85+
},
86+
id: 'dateOfBirth',
87+
},
88+
{
89+
label: 'Age in Days',
90+
type: 'obs',
91+
questionOptions: {
92+
rendering: 'number',
93+
concept: 'age_in_days_concept',
94+
},
95+
id: 'ageInDays',
96+
},
7997
];
8098

8199
export const fields: Array<FormField> = [
@@ -180,6 +198,8 @@ describe('Expression runner', () => {
180198
htsProviderRemarks: '',
181199
referredToPreventionServices: [],
182200
bodyTemperature: 0,
201+
dateOfBirth: '',
202+
ageInDays: 0,
183203
no_interest: '',
184204
depressed: '',
185205
bad_sleep: '',
@@ -199,6 +219,8 @@ describe('Expression runner', () => {
199219
htsProviderRemarks: '',
200220
referredToPreventionServices: [],
201221
bodyTemperature: 0,
222+
dateOfBirth: '',
223+
ageInDays: 0,
202224
no_interest: '',
203225
depressed: '',
204226
bad_sleep: '',
@@ -360,4 +382,25 @@ describe('Expression runner', () => {
360382
);
361383
expect(result).toEqual(5);
362384
});
385+
386+
it('should calculate age in days using dayjs diff expression', () => {
387+
// setup - use a known date 30 days ago
388+
const thirtyDaysAgo = new Date();
389+
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
390+
const dateOfBirthString = thirtyDaysAgo.toISOString().split('T')[0];
391+
valuesMap['dateOfBirth'] = dateOfBirthString;
392+
393+
// Calculate days difference
394+
const result = evaluateExpression(
395+
"dayjs().diff(dayjs(dateOfBirth), 'day')",
396+
{ value: allFields[6], type: 'field' },
397+
allFields,
398+
valuesMap,
399+
context,
400+
);
401+
402+
// Should be approximately 30 days (allowing for time-of-day variations)
403+
expect(result).toBeGreaterThanOrEqual(29);
404+
expect(result).toBeLessThanOrEqual(31);
405+
});
363406
});

0 commit comments

Comments
 (0)