Skip to content

Commit b31d9de

Browse files
authored
Merge pull request #172 from EyeSeeTea/enhancement/analytics-enrollments-query-options
Add all the options in /analytics/enrollments/query endpoint accordinng to documentation
2 parents d5f0e5e + 3bd2a0a commit b31d9de

2 files changed

Lines changed: 165 additions & 20 deletions

File tree

README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,37 @@ const analyticsData = await api.analytics
271271

272272
```ts
273273
const analyticsData = await api.analytics
274-
.getEnrollmentsQuery("IpHINAT79UW", {
275-
dimension: ["GxdhnY5wmHq", "ou:ImspTQPwCqd"],
276-
enrollmentDate: "LAST_12_MONTHS,THIS_MONTH",
274+
.getEnrollmentsQuery({
275+
programId: "IpHINAT79UW",
276+
dimension: ["cejWyOfXge6", "lZGmxYbs97q", "ou:USER_ORGUNIT", "w75KJ2mc4zz", "zDhUuAYrxNC"],
277+
programStatus: "ACTIVE",
278+
})
279+
.getData();
280+
```
281+
282+
Disable pagination:
283+
284+
```ts
285+
const analyticsData = await api.analytics
286+
.getEnrollmentsQuery({
287+
programId: "IpHINAT79UW",
288+
dimension: ["cejWyOfXge6", "lZGmxYbs97q", "ou:USER_ORGUNIT", "w75KJ2mc4zz", "zDhUuAYrxNC"],
289+
programStatus: "ACTIVE",
290+
paging: false,
291+
})
292+
.getData();
293+
```
294+
295+
Get pagination and total pages:
296+
297+
```ts
298+
const analyticsData = await api.analytics
299+
.getEnrollmentsQuery({
300+
programId: "IpHINAT79UW",
301+
dimension: ["cejWyOfXge6", "lZGmxYbs97q", "ou:USER_ORGUNIT", "w75KJ2mc4zz", "zDhUuAYrxNC"],
302+
programStatus: "ACTIVE",
303+
paging: true,
304+
totalPages: true,
277305
})
278306
.getData();
279307
```

src/api/analytics.ts

Lines changed: 134 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,23 @@ import { Id } from "../schemas";
22
import { EmptyObject } from "../utils/types";
33
import { D2ApiResponse, HttpResponse } from "./common";
44
import { D2ApiGeneric } from "./d2Api";
5-
import { Pager } from "./model";
65

76
type Operator = "EQ" | "GT" | "GE" | "LT" | "LE";
87

8+
type ColumnsSeparatedBySemicolon = string;
9+
10+
type RowsSeparatedBySemicolon = string;
11+
12+
type UserOrgUnitSeparatedBySemicolon = string;
13+
914
export type AnalyticsOptions = {
15+
/** Dimensions and dimension items to be retrieved, repeated for each */
1016
dimension: string[];
17+
18+
/** Filters and filter items to apply to the query, repeated for each. */
1119
filter?: string[];
20+
21+
/** Aggregation type to use in the aggregation process. */
1222
aggregationType?:
1323
| "SUM"
1424
| "AVERAGE"
@@ -20,44 +30,136 @@ export type AnalyticsOptions = {
2030
| "VARIANCE"
2131
| "MIN"
2232
| "MAX";
33+
34+
/** Filters for the data/measures. */
2335
measureCriteria?: Operator;
36+
37+
/** Filters for the data/measure, applied before aggregation is performed. */
2438
preAggregationMeasureCriteria?: Operator;
39+
40+
/** Start date for a date range. Will be applied as a filter. Can not be used together with a period dimension or filter. (yyyy-MM-dd) */
2541
startDate?: string;
42+
43+
/** End date for date range. Will be applied as a filter. Can not be used together with a period dimension or filter. (yyyy-MM-dd) */
2644
endDate?: string;
45+
46+
/** Exclude the metadata part of the response (improves performance). */
2747
skipMeta?: boolean;
48+
49+
/** Exclude the data part of the response. */
2850
skipData?: boolean;
51+
52+
/** Skip rounding of data values, i.e. provide full precision. */
2953
skipRounding?: boolean;
54+
55+
/** Include names of organisation unit ancestors and hierarchy paths of organisation units in the metadata. */
3056
hierarchyMeta?: boolean;
57+
58+
/** Ignore limit on max 50 000 records in response - use with care. */
3159
ignoreLimit?: boolean;
60+
61+
/** Use plain data source or table layout for the response. */
3262
tableLayout?: boolean;
63+
64+
/** Hides empty rows in response, applicable when table layout is true. */
3365
hideEmptyRows?: boolean;
66+
67+
/** Hides empty columns in response, applicable when table layout is true. */
3468
hideEmptyColumns?: boolean;
69+
70+
/** Display full org unit hierarchy path together with org unit name. */
3571
showHierarchy?: boolean;
72+
73+
/** Include the numerator and denominator used to calculate the value in the response. */
3674
includeNumDen?: boolean;
75+
76+
/** Include metadata details to raw data response. */
3777
includeMetadataDetails?: boolean;
78+
79+
/** Property to display for metadata. */
3880
displayProperty?: "NAME" | "SHORTNAME";
81+
82+
/** Identifier scheme used for metadata items in the query response. It accepts identifier, code or attributes. */
3983
outputIdScheme?: string;
84+
85+
/** Identifier scheme to use for metadata items in the query request, can be an identifier, code or attributes. */
4086
inputIdScheme?: string;
87+
88+
/** Include data which has been approved at least up to the given approval level, refers to identifier of approval level. */
4189
approvalLevel?: string;
90+
91+
/** Date used as basis for relative periods. */
4292
relativePeriodDate?: string;
43-
userOrgUnit?: string;
44-
columns?: string;
45-
rows?: string;
93+
94+
/** Explicitly define the user org units to utilize, overrides organisation units associated with the current user, multiple identifiers can be separated by semicolon. */
95+
userOrgUnit?: UserOrgUnitSeparatedBySemicolon;
96+
97+
/** Dimensions to use as columns for table layout. */
98+
columns?: ColumnsSeparatedBySemicolon;
99+
100+
/** Dimensions to use as rows for table layout. */
101+
rows?: RowsSeparatedBySemicolon;
102+
103+
/** Specify the ordering of rows based on value. */
46104
order?: "ASC" | "DESC";
105+
106+
/** The time field to base event aggregation on. Applies to event data items only. Can be a predefined option or the ID of an attribute or data element with a time-based value type. */
47107
timeField?: string;
108+
109+
/** The organisation unit field to base event aggregation on. Applies to event data items only. Can be the ID of an attribute or data element with the Organisation unit value type. The default option is specified as omitting the query parameter. */
48110
orgUnitField?: string;
111+
112+
/** Custom period on enrollmentDate */
49113
enrollmentDate?: string;
50114
};
51115

116+
type KnownAscDescValues =
117+
| "ouname"
118+
| "programstatus"
119+
| "createdbydisplayname"
120+
| "lastupdatedbydisplayname"
121+
| "enrollmentdate"
122+
| "incidentdate"
123+
| "lastupdated";
124+
125+
type AscDescParameter = KnownAscDescValues | Id;
126+
127+
type PageOptions = {
128+
totalPages: boolean;
129+
page: number;
130+
pageSize: number;
131+
paging: boolean;
132+
};
133+
134+
type HeadersSeparatedByCommas = string;
135+
52136
export type GetEnrollmentsQueryOptions = {
53137
programId: Id;
54-
} & AnalyticsOptions;
138+
programStatus?: "ACTIVE" | "COMPLETED" | "CANCELLED";
139+
ouMode?: "DESCENDANTS" | "CHILDREN" | "SELECTED";
140+
asc?: AscDescParameter;
141+
desc?: AscDescParameter;
142+
coordinatesOnly?: boolean;
143+
headers?: HeadersSeparatedByCommas;
144+
} & AnalyticsOptions &
145+
Partial<PageOptions>;
146+
147+
type PaginationOptions = Pick<GetEnrollmentsQueryOptions, "paging" | "totalPages" | "skipMeta">;
148+
149+
type PagerWithoutTotals = { page: number; pageSize: number; isLastPage: boolean };
150+
151+
type PagerWithTotals = { page: number; pageCount: number; pageSize: number; total: number };
152+
153+
type MetadataPager<Options extends PaginationOptions> = Options["paging"] extends false
154+
? undefined
155+
: (Options["totalPages"] extends true ? PagerWithTotals : PagerWithoutTotals);
156+
55157
export type AnalyticsResponse = {
56158
headers: Array<{
57-
name: "dx" | "dy";
58-
column: "Data";
59-
valueType: "TEXT" | "NUMBER";
60-
type: "java.lang.String" | "java.lang.Double";
159+
name: string;
160+
column: string;
161+
valueType: string;
162+
type: string;
61163
hidden: boolean;
62164
meta: boolean;
63165
}>;
@@ -66,13 +168,17 @@ export type AnalyticsResponse = {
66168
| {
67169
dimensions: Record<string, string[]>;
68170
items: Record<string, { name: string; uid?: Id; code?: string; options: any[] }>;
69-
pager?: Pager;
70171
};
172+
71173
rows: Array<string[]>;
72174
width: number;
73175
height: number;
74176
};
75177

178+
type AnalyticsResponseWithPager<Options extends GetEnrollmentsQueryOptions> = AnalyticsResponse & {
179+
metaData: { pager: MetadataPager<Options> };
180+
};
181+
76182
export type RunAnalyticsResponse = HttpResponse<{
77183
id: string;
78184
created: string;
@@ -86,10 +192,22 @@ export type RunAnalyticsResponse = HttpResponse<{
86192
}>;
87193

88194
export type RunAnalyticsOptions = {
195+
/** Skip generation of resource tables */
89196
skipResourceTables?: boolean;
197+
198+
/** Skip generation of aggregate data and completeness data */
90199
skipAggregate?: boolean;
200+
201+
/** Skip generation of event data */
91202
skipEvents?: boolean;
203+
204+
/** Skip generation of enrollment data */
92205
skipEnrollment?: boolean;
206+
207+
/** Skip generation of organization unit ownership data */
208+
skipOrgUnitOwnership?: boolean;
209+
210+
/** Number of last years of data to include */
93211
lastYears?: number;
94212
};
95213

@@ -101,13 +219,12 @@ export class Analytics {
101219
}
102220

103221
// https://docs.dhis2.org/en/develop/using-the-api/dhis-core-version-240/analytics.html#webapi_enrollment_analytics
104-
getEnrollmentsQuery({
105-
programId,
106-
...options
107-
}: GetEnrollmentsQueryOptions): D2ApiResponse<AnalyticsResponse> {
108-
return this.d2Api.get<AnalyticsResponse>(
109-
`/analytics/enrollments/query/${programId}`,
110-
options as AnalyticsOptions
222+
getEnrollmentsQuery<Options extends GetEnrollmentsQueryOptions>(
223+
options: Options
224+
): D2ApiResponse<AnalyticsResponseWithPager<Options>> {
225+
return this.d2Api.get<AnalyticsResponseWithPager<Options>>(
226+
`/analytics/enrollments/query/${options.programId}`,
227+
options
111228
);
112229
}
113230

0 commit comments

Comments
 (0)