Skip to content

Commit 837c7fe

Browse files
Benmuirurilatin-pandatatilepizsRafa
authored
feat(#9231): add filter in aggregate targets (#9317)
Co-authored-by: Jennifer Q <[email protected]> Co-authored-by: Tatiana Lépiz Soto <[email protected]> Co-authored-by: Rafa <[email protected]>
1 parent 1a59345 commit 837c7fe

38 files changed

+2555
-582
lines changed

api/resources/translations/messages-en.properties

+2
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ analytics.target.aggregates.reported = Reported
349349
analytics.target.aggregates.select.error = Error loading target aggregate.
350350
analytics.target.aggregates.supervisees.meeting.goal = CHWs meeting goal
351351
analytics.target.aggregates.total = Total
352+
analytics.target.aggregates.reporting_period = Reporting period
352353
analytics.target.goal = Goal
353354
analytics.target.goal.help = If you don't want to display a goal enter a value of "-1".
354355
analytics.target.icon = Icon
@@ -1327,6 +1328,7 @@ targets.pnc_registrations.title = PNC registrations
13271328
targets.pnc_visits.title = PNC visits
13281329
targets.pregnancy_registrations.title = New pregnancies
13291330
targets.this_month.subtitle = This month
1331+
targets.last_month.subtitle = Last month
13301332
targets.vaccines_given.title = Vaccines given
13311333
task.date = Due date
13321334
task.days.left = {DAYS, plural, one{1 day left} other{\# days left}}

api/resources/translations/messages-es.properties

+3-1
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ analytics.target.aggregates.reported = Reportado
349349
analytics.target.aggregates.select.error = Error al cargar el objetivo consolidado.
350350
analytics.target.aggregates.supervisees.meeting.goal = Promotores de salud comunitaria que alcanzaron la meta.
351351
analytics.target.aggregates.total = Total
352+
analytics.target.aggregates.reporting_period = Periodo del informe
352353
analytics.target.goal = Meta
353354
analytics.target.goal.help = Si no desea mostrar una meta, ingrese el valor de "-1".
354355
analytics.target.icon = Icono
@@ -638,7 +639,7 @@ email.invalid = Dirección de correo electrónico no válida.
638639
empty = El mensaje esta en blanco, por favor reenvielo. Si continua teniendo problemas, informe a su supervisor.
639640
enketo.constraint.invalid = Valor no permitido
640641
enketo.constraint.required = Este campo es obligatorio
641-
enketo.drawwidget.annotation = anotación
642+
enketo.drawwidget.annotation = anotación
642643
enketo.drawwidget.drawing = dibujo
643644
enketo.drawwidget.signature = firma
644645
enketo.error.max_attachment_size = Los archivos subidos exceden el límite de tamaño total. Suba archivos más pequeños.
@@ -1327,6 +1328,7 @@ targets.pnc_registrations.title = Registros de CP
13271328
targets.pnc_visits.title = Visitas de CP
13281329
targets.pregnancy_registrations.title = Nuevos embarazos
13291330
targets.this_month.subtitle = Este mes
1331+
targets.last_month.subtitle = El mes pasado
13301332
targets.vaccines_given.title = Vacunas administradas
13311333
task.date = Fecha límite
13321334
task.days.left = {DAYS, plural, one{falta 1 día} other{faltan \# dias}}

api/resources/translations/messages-fr.properties

+2
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ analytics.target.aggregates.reported = Signalé
349349
analytics.target.aggregates.select.error = Erreur lors du chargement de l'agrégat objectif.
350350
analytics.target.aggregates.supervisees.meeting.goal = ASC qui ont atteint l'objectif
351351
analytics.target.aggregates.total = Total
352+
analytics.target.aggregates.reporting_period = Période des rapports
352353
analytics.target.goal = But
353354
analytics.target.goal.help = Si vous ne souhaitez pas afficher d'objectif, saisissez la valeur "-1".
354355
analytics.target.icon = Icone
@@ -1327,6 +1328,7 @@ targets.pnc_registrations.title = Enregistrements CPoN
13271328
targets.pnc_visits.title = Visites CPoN
13281329
targets.pregnancy_registrations.title = Nouvelles grossesses
13291330
targets.this_month.subtitle = Ce mois
1331+
targets.last_month.subtitle = Le mois dernier
13301332
targets.vaccines_given.title = Vaccins donnés
13311333
task.date = Date d'échéance
13321334
task.days.left = {JOURS, plural, one{1 jour restant} other{\# jours restants}}

api/resources/translations/messages-id.properties

+2
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ analytics.target.aggregates.reported =
344344
analytics.target.aggregates.select.error =
345345
analytics.target.aggregates.supervisees.meeting.goal =
346346
analytics.target.aggregates.total =
347+
analytics.target.aggregates.reporting_period = Periode pelaporan
347348
analytics.target.goal = Tujuan
348349
analytics.target.goal.help =
349350
analytics.target.icon = Icon
@@ -1244,6 +1245,7 @@ targets.pnc_registrations.title =
12441245
targets.pnc_visits.title =
12451246
targets.pregnancy_registrations.title = Kehamilan terdaftar
12461247
targets.this_month.subtitle = Bulan ini
1248+
targets.last_month.subtitle = Bulan sebelumnya
12471249
targets.vaccines_given.title = Vaksin yang diberikan
12481250
task.date = Batas Tanggal Terakhir
12491251
task.days.left =

api/resources/translations/messages-ne.properties

+3-1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ analytics.target.aggregates.reported =
348348
analytics.target.aggregates.select.error =
349349
analytics.target.aggregates.supervisees.meeting.goal =
350350
analytics.target.aggregates.total =
351+
analytics.target.aggregates.reporting_period = रिपोर्टिङ अवधि
351352
analytics.target.goal =
352353
analytics.target.goal.help =
353354
analytics.target.icon =
@@ -1253,7 +1254,8 @@ targets.past_3mos.subtitle =
12531254
targets.pnc_registrations.title =
12541255
targets.pnc_visits.title =
12551256
targets.pregnancy_registrations.title =
1256-
targets.this_month.subtitle =
1257+
targets.this_month.subtitle = यो महिना
1258+
targets.last_month.subtitle = अघिल्लो महिना
12571259
targets.vaccines_given.title =
12581260
task.date = अनुमानित मिति
12591261
task.days.left =

api/resources/translations/messages-sw.properties

+2
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ analytics.target.aggregates.reported = Imeripotiwa
349349
analytics.target.aggregates.select.error = Hitilafu katika kupakia jumla ya malengo
350350
analytics.target.aggregates.supervisees.meeting.goal = Wafanyikazi wa afya wa Jamii wanafikisha lengo
351351
analytics.target.aggregates.total = Jumla
352+
analytics.target.aggregates.reporting_period = Kipindi cha kuripoti
352353
analytics.target.goal = Lengo
353354
analytics.target.goal.help = Ikiwa hutaki kuonyesha lengo weka thamani ya "-1"
354355
analytics.target.icon = Ikoni
@@ -1327,6 +1328,7 @@ targets.pnc_registrations.title = Usajili wa PNC
13271328
targets.pnc_visits.title = Ziara za PNC
13281329
targets.pregnancy_registrations.title = Mimba mpya
13291330
targets.this_month.subtitle = Mwezi huu
1331+
targets.last_month.subtitle = Mwezi uliopita
13301332
targets.vaccines_given.title = Chanjo iliyopewa
13311333
task.date = Tarehe ya kukamilisha
13321334
task.days.left = {DAYS, plural, one{Imesalia siku 1} other{Zimesalia siku \#}}

shared-libs/calendar-interval/src/index.js

+16
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ const getInterval = (intervalStartDate, referenceDate = moment()) => {
5050
};
5151
};
5252

53+
const getPreviousInterval = (intervalStartDate, referenceDate = moment()) => {
54+
referenceDate = referenceDate.clone().subtract(1, 'month');
55+
return getInterval(intervalStartDate, referenceDate);
56+
};
57+
5358
module.exports = {
5459
// Returns the timestamps of the start and end of the current calendar interval
5560
// @param {Number} [intervalStartDate=1] - day of month when interval starts (1 - 31)
@@ -59,6 +64,17 @@ module.exports = {
5964
// [12-31 -> 01-30], [01-31 -> 02-[28|29]], [03-01 -> 03-30], [03-31 -> 04-30], [05-01 -> 05-30], [05-31 - 06-30]
6065
getCurrent: (intervalStartDate) => getInterval(intervalStartDate),
6166

67+
/** Returns the timestamps of the start and the end of the previous calendar interval
68+
* intervalStartDate: Number. Day of the month when interval starts
69+
* referenceDate: Date.
70+
*/
71+
getPrevious: (intervalStartDate, referenceDate) => {
72+
if (referenceDate) {
73+
return getPreviousInterval(intervalStartDate, moment(referenceDate));
74+
}
75+
return getPreviousInterval(intervalStartDate);
76+
},
77+
6278
/**
6379
* Returns the timestamps of the start and end of the a calendar interval that contains a reference date
6480
* @param {Number} [intervalStartDate=1] - day of month when interval starts (1 - 31)

shared-libs/calendar-interval/test/index.js

+74
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,80 @@ describe('CalendarInterval', () => {
252252
});
253253
});
254254

255+
describe('getPrevious', () => {
256+
it('returns 1st of previous month when month start is 1', () => {
257+
clock = sinon.useFakeTimers(moment('2024-07-15 21:10:01').valueOf());
258+
chai.expect(service.getPrevious(1)).to.deep.equal({
259+
start: moment('2024-06-01 00:00:00').valueOf(),
260+
end: moment('2024-06-30 23:59:59:999').valueOf(),
261+
});
262+
clock.restore();
263+
});
264+
265+
it('returns 1st of previous month when reference date is provided', () => {
266+
const referenceDate = '2024-07-15';
267+
chai.expect(service.getPrevious(1, referenceDate)).to.deep.equal({
268+
start: moment('2024-06-01 00:00:00').valueOf(),
269+
end: moment('2024-06-30 23:59:59:999').valueOf(),
270+
});
271+
});
272+
273+
it('returns 1st of previous month when reference date provided is in the future', () => {
274+
const referenceDate = '2025-07-15';
275+
chai.expect(service.getPrevious(1, referenceDate)).to.deep.equal({
276+
start: moment('2025-06-01 00:00:00').valueOf(),
277+
end: moment('2025-06-30 23:59:59:999').valueOf(),
278+
});
279+
});
280+
281+
it('returns n-th of the previous month when month start is n <= current date', () => {
282+
clock = sinon.useFakeTimers(moment('2018-03-20 21:10:01').valueOf());
283+
chai.expect(service.getPrevious(15)).to.deep.equal({
284+
start: moment('2018-02-15 00:00:00').valueOf(),
285+
end: moment('2018-03-14 23:59:59:999').valueOf(),
286+
});
287+
clock.restore();
288+
});
289+
290+
it('returns n-th of two months ago when month start is n > current date', () => {
291+
clock = sinon.useFakeTimers(moment('2018-03-10 21:10:01').valueOf());
292+
chai.expect(service.getPrevious(20)).to.deep.equal({
293+
start: moment('2018-01-20 00:00:00').valueOf(),
294+
end: moment('2018-02-19 23:59:59:999').valueOf(),
295+
});
296+
clock.restore();
297+
});
298+
299+
it('returns correct previous period when incorrect start date values', () => {
300+
clock = sinon.useFakeTimers(moment('2018-02-10').valueOf());
301+
[null, undefined, -1, 'date', false, 0, 35].forEach((invalidStart) => {
302+
chai.expect(service.getPrevious(invalidStart)).to.deep.equal({
303+
start: moment('2018-01-01 00:00:00').valueOf(),
304+
end: moment('2018-01-31 23:59:59:999').valueOf(),
305+
});
306+
});
307+
clock.restore();
308+
});
309+
310+
it('returns correct previous period when start date same as current date', () => {
311+
clock = sinon.useFakeTimers(moment('2018-04-15').valueOf());
312+
chai.expect(service.getPrevious(15)).to.deep.equal({
313+
start: moment('2018-03-15 00:00:00').valueOf(),
314+
end: moment('2018-04-14 23:59:59:999').valueOf(),
315+
});
316+
clock.restore();
317+
});
318+
319+
it('returns correct start date in previous month if month has 30 days', () => {
320+
clock = sinon.useFakeTimers(moment('2018-05-15').valueOf());
321+
chai.expect(service.getPrevious(31)).to.deep.equal({
322+
start: moment('2018-03-31 00:00:00').valueOf(),
323+
end: moment('2018-04-30 23:59:59:999').valueOf(),
324+
});
325+
clock.restore();
326+
});
327+
});
328+
255329
describe('getInterval', () => {
256330
it('returns 1st of current month when month start is not set or incorrect', () => {
257331
let timestamp;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const TARGETS_DEFAULT_CONFIG = [
2+
{
3+
id: 'count_no_goal',
4+
type: 'count',
5+
title: 'count no goal',
6+
aggregate: true,
7+
subtitle_translation_key: 'targets.all_time.subtitle'
8+
},
9+
{
10+
id: 'count_with_goal',
11+
type: 'count',
12+
title: 'count with goal',
13+
goal: 20,
14+
aggregate: true,
15+
subtitle_translation_key: 'targets.all_time.subtitle'
16+
},
17+
{
18+
id: 'percent_no_goal',
19+
type: 'percent',
20+
title: 'percent no goal',
21+
aggregate: true,
22+
subtitle_translation_key: 'targets.all_time.subtitle'
23+
},
24+
{
25+
id: 'percent_with_goal',
26+
type: 'percent',
27+
title: 'percent with goal',
28+
aggregate: true, goal: 80,
29+
subtitle_translation_key: 'targets.this_month.subtitle'
30+
},
31+
{
32+
id: 'percent_achieved',
33+
type: 'percent',
34+
title: 'percent achieved',
35+
aggregate: true, goal: 10,
36+
subtitle_translation_key: 'targets.this_month.subtitle'
37+
},
38+
];
39+
40+
const TARGETS_CONFIG_WITH_AND_WITHOUT_AGGREGATES = [
41+
{ id: 'not_aggregate', type: 'count', title: 'my task' },
42+
{ id: 'also_not_aggregate', type: 'count', title: 'my task' },
43+
{ id: 'also_also_not_aggregate', type: 'count', title: 'my task', aggregate: false },
44+
...TARGETS_DEFAULT_CONFIG
45+
];
46+
47+
const EXPECTED_DEFAULTS_TARGETS = [
48+
{ id: 'count_no_goal', title: 'count no goal', progressBar: false, goal: false, counter: '25' },
49+
{ id: 'count_with_goal', title: 'count with goal', progressBar: true, goal: 20, counter: '0 of 5' },
50+
{ id: 'percent_no_goal', title: 'percent no goal', progressBar: true, goal: false, counter: '50%' },
51+
{ id: 'percent_with_goal', title: 'percent with goal', progressBar: true, goal: '80%', counter: '5 of 5' },
52+
{ id: 'percent_achieved', title: 'percent achieved', progressBar: true, goal: '10%', counter: '5 of 5' },
53+
];
54+
55+
const EXPECTED_TARGETS_NO_PROGRESS = [
56+
{ id: 'count_no_goal', title: 'count no goal', counter: '0', progressBar: false, goal: false },
57+
{ id: 'count_with_goal', title: 'count with goal', counter: '0 of 5', progressBar: true, goal: 20 },
58+
{ id: 'percent_no_goal', title: 'percent no goal', counter: '0%', progressBar: true, goal: false },
59+
{ id: 'percent_with_goal', title: 'percent with goal', counter: '0 of 5', progressBar: true, goal: '80%' },
60+
{ id: 'percent_achieved', title: 'percent achieved', counter: '0 of 5', progressBar: true, goal: '10%', },
61+
];
62+
63+
module.exports = {
64+
TARGETS_DEFAULT_CONFIG,
65+
TARGETS_CONFIG_WITH_AND_WITHOUT_AGGREGATES,
66+
EXPECTED_DEFAULTS_TARGETS,
67+
EXPECTED_TARGETS_NO_PROGRESS,
68+
};

0 commit comments

Comments
 (0)