Skip to content

Commit

Permalink
[nools] extend date options for contact-based targets
Browse files Browse the repository at this point in the history
Add support for:

* 'now'
* 'reported'

Closes #94
  • Loading branch information
alxndrsn committed Oct 29, 2018
1 parent acc3cb2 commit aaa65ed
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v1.18.12
* [nools] extend date options for contact-based targets
* [nools/lib] Add missing linebreak

## v1.18.11
* [travis] fix tests
* Added license information for contributions
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "medic-conf",
"version": "1.18.11",
"version": "1.18.12",
"description": "Configure Medic Mobile deployments",
"main": "index.js",
"scripts": {
Expand Down
10 changes: 9 additions & 1 deletion src/nools/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,15 @@ function emitContactBasedTargetFor(c, targetConfig) {
var pass = !targetConfig.passesIf || !!targetConfig.passesIf(c);

var instance = createTargetInstance(targetConfig.id, c.contact, pass);
instance.date = targetConfig.date ? targetConfig.date(c) : now.getTime();
if(typeof targetConfig.date === 'function') {
instance.date = targetConfig.date(c);
} else if(targetConfig.date === undefined || targetConfig.date === 'now') {
instance.date = now.getTime();
} else if(targetConfig.date === 'reported') {
instance.date = c.reported_date;
} else {
throw new Error('Unrecognised value for target.date: ' + targetConfig.date);
}
emitTargetInstance(instance);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"contact_summary": "",
"tasks": {
"rules": "define Target {_id: null,deleted: null,type: null,pass: null,date: null}define Contact {contact: null,reports: null}define Task {_id: null,deleted: null,doc: null,contact: null,icon: null,date: null,title: null,fields: null,resolved: null,priority: null,priorityLabel: null,reports: null,actions: null}rule GenerateEvents {when {c: Contact}then {var idx1,idx2,r,target,now=Utils.now(),targets=[{id:'active-pregnancies',appliesTo:'reports',date:'now',appliesIf:function(e,t){return'D'===t.form}},{id:'imm-children-registered-this-month',appliesTo:'contacts',date:function(e){return e.contact.reported_date},appliesToType:['person'],appliesIf:function(e){return e.age_in_months<=60}}],tasks=[];for(idx1=0;idx1<targets.length;++idx1)switch((target=targets[idx1]).appliesTo){case'contacts':c.contact&&-1!==target.appliesToType.indexOf(c.contact.type)&&emitContactBasedTargetFor(c,target);break;case'reports':for(idx2=0;idx2<c.reports.length;++idx2)r=c.reports[idx2],emitReportBasedTargetFor(c,r,target);break;default:throw new Error('unrecognised target type: '+target.appliesTo)}if(tasks)for(idx1=0;idx1<tasks.length;++idx1){var task=tasks[idx1];switch(task.appliesTo){case'reports':case'scheduled_tasks':for(idx2=0;idx2<c.reports.length;++idx2)r=c.reports[idx2],emitTasksForSchedule(c,task,r);break;case'contacts':c.contact&&-1!==task.appliesToType.indexOf(c.contact.type)&&emitTasksForSchedule(c,task);break;default:throw new Error('unrecognised task type: '+task.appliesTo)}}function emitTasksForSchedule(o,d,n){var e;if((!n||!d.appliesToType||-1!==d.appliesToType.indexOf(n.form))&&('scheduled_tasks'===d.appliesTo||!d.appliesIf||d.appliesIf(o,n)))if('scheduled_tasks'===d.appliesTo){if(n&&d.appliesIf){if(!n.scheduled_tasks)return;for(e=0;e<n.scheduled_tasks.length;e++)d.appliesIf(o,n,e)&&t(e)}}else t();function t(e){var t,a,s,i,r=null;for(t=0;t<d.events.length;t++)a=d.events[t],r=n?a.dueDate?a.dueDate(n,a,e):void 0!==e?new Date(Utils.addDate(new Date(n.scheduled_tasks[e].due),a.days)):new Date(Utils.addDate(new Date(n.reported_date),a.days)):a.dueDate?a.dueDate(o.contact,a):new Date(Utils.addDate(new Date(o.contact.reported_date),a.days)),Utils.isTimely(r,a)&&(i={_id:n?n._id+'-'+a.id:o.contact._id+'-'+d.id,deleted:!(!(o.contact&&o.contact.deleted||n)||!n.deleted),doc:o,contact:o.contact,icon:d.icon,date:r,title:d.title,resolved:!!n&&d.resolvedIf(o,n,a,r,e),actions:n?d.actions.map(c):[]},void 0!==e&&(i._id+='-'+e),'function'==typeof(s=d.priority)&&(s=s(o,n)),s&&(i.priority=s.level,i.priorityLabel=s.label),emit('task',new Task(i)))}function c(e){return{type:'report',form:e.form,label:e.label||'Follow up',content:{source:'task',source_id:n._id,contact:o.contact}}}}function emitContactBasedTargetFor(e,t){if(!t.appliesIf||t.appliesIf(e)){var a=!t.passesIf||!!t.passesIf(e),s=createTargetInstance(t.id,e.contact,a);s.date=t.date?t.date(e):now.getTime(),emitTargetInstance(s)}}function emitReportBasedTargetFor(e,t,a){var s,i;if(!a.appliesIf||a.appliesIf(e,t))if(a.emitCustom)a.emitCustom(e,t);else switch(i=!a.passesIf||!!a.passesIf(e,t),(s=createTargetInstance(a.id,t,i))._id=('report'===a.idType?t._id:e.contact._id)+'-'+a.id,emitTargetInstance(s),a.date){case'now':s.date=now.getTime()}}function createTargetInstance(e,t,a){return new Target({_id:t._id+'-'+e,deleted:!!t.deleted,type:e,pass:a,date:t.reported_date})}function emitTargetInstance(e){emit('target',e)}emit('_complete',{_id:!0});}}",
"rules": "define Target {_id: null,deleted: null,type: null,pass: null,date: null}define Contact {contact: null,reports: null}define Task {_id: null,deleted: null,doc: null,contact: null,icon: null,date: null,title: null,fields: null,resolved: null,priority: null,priorityLabel: null,reports: null,actions: null}rule GenerateEvents {when {c: Contact}then {var idx1,idx2,r,target,now=Utils.now(),targets=[{id:'active-pregnancies',appliesTo:'reports',date:'now',appliesIf:function(e,t){return'D'===t.form}},{id:'imm-children-registered-this-month',appliesTo:'contacts',date:function(e){return e.contact.reported_date},appliesToType:['person'],appliesIf:function(e){return e.age_in_months<=60}}],tasks=[];for(idx1=0;idx1<targets.length;++idx1)switch((target=targets[idx1]).appliesTo){case'contacts':c.contact&&-1!==target.appliesToType.indexOf(c.contact.type)&&emitContactBasedTargetFor(c,target);break;case'reports':for(idx2=0;idx2<c.reports.length;++idx2)r=c.reports[idx2],emitReportBasedTargetFor(c,r,target);break;default:throw new Error('unrecognised target type: '+target.appliesTo)}if(tasks)for(idx1=0;idx1<tasks.length;++idx1){var task=tasks[idx1];switch(task.appliesTo){case'reports':case'scheduled_tasks':for(idx2=0;idx2<c.reports.length;++idx2)r=c.reports[idx2],emitTasksForSchedule(c,task,r);break;case'contacts':c.contact&&-1!==task.appliesToType.indexOf(c.contact.type)&&emitTasksForSchedule(c,task);break;default:throw new Error('unrecognised task type: '+task.appliesTo)}}function emitTasksForSchedule(d,o,n){var e;if((!n||!o.appliesToType||-1!==o.appliesToType.indexOf(n.form))&&('scheduled_tasks'===o.appliesTo||!o.appliesIf||o.appliesIf(d,n)))if('scheduled_tasks'===o.appliesTo){if(n&&o.appliesIf){if(!n.scheduled_tasks)return;for(e=0;e<n.scheduled_tasks.length;e++)o.appliesIf(d,n,e)&&t(e)}}else t();function t(e){var t,a,s,i,r=null;for(t=0;t<o.events.length;t++)a=o.events[t],r=n?a.dueDate?a.dueDate(n,a,e):void 0!==e?new Date(Utils.addDate(new Date(n.scheduled_tasks[e].due),a.days)):new Date(Utils.addDate(new Date(n.reported_date),a.days)):a.dueDate?a.dueDate(d.contact,a):new Date(Utils.addDate(new Date(d.contact.reported_date),a.days)),Utils.isTimely(r,a)&&(i={_id:n?n._id+'-'+a.id:d.contact._id+'-'+o.id,deleted:!(!(d.contact&&d.contact.deleted||n)||!n.deleted),doc:d,contact:d.contact,icon:o.icon,date:r,title:o.title,resolved:!!n&&o.resolvedIf(d,n,a,r,e),actions:n?o.actions.map(c):[]},void 0!==e&&(i._id+='-'+e),'function'==typeof(s=o.priority)&&(s=s(d,n)),s&&(i.priority=s.level,i.priorityLabel=s.label),emit('task',new Task(i)))}function c(e){return{type:'report',form:e.form,label:e.label||'Follow up',content:{source:'task',source_id:n._id,contact:d.contact}}}}function emitContactBasedTargetFor(e,t){if(!t.appliesIf||t.appliesIf(e)){var a=!t.passesIf||!!t.passesIf(e),s=createTargetInstance(t.id,e.contact,a);if('function'==typeof t.date)s.date=t.date(e);else if(void 0===t.date||'now'===t.date)s.date=now.getTime();else{if('reported'!==t.date)throw new Error('Unrecognised value for instance.date: '+t.date);s.date=e.reported_date}emitTargetInstance(s)}}function emitReportBasedTargetFor(e,t,a){var s,i;if(!a.appliesIf||a.appliesIf(e,t))if(a.emitCustom)a.emitCustom(e,t);else switch(i=!a.passesIf||!!a.passesIf(e,t),(s=createTargetInstance(a.id,t,i))._id=('report'===a.idType?t._id:e.contact._id)+'-'+a.id,emitTargetInstance(s),a.date){case'now':s.date=now.getTime()}}function createTargetInstance(e,t,a){return new Target({_id:t._id+'-'+e,deleted:!!t.deleted,type:e,pass:a,date:t.reported_date})}function emitTargetInstance(e){emit('target',e)}emit('_complete',{_id:!0});}}",
"schedules": {
"test": true
},
Expand Down
48 changes: 48 additions & 0 deletions test/nools/lib.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,50 @@ describe('nools lib', function() {
// when
const emitted = loadLibWith(config).emitted;

// then
assert.deepEqual(emitted, [
{ _type:'target', date:TEST_DATE },
{ _type:'_complete', _id:true },
]);
});
it('should allow "reported" as target date', function() {
// given
const target = aPersonBasedTarget();
target.date = 'reported';
// and
const reportedDate = aRandomTimestamp();
const contact = personWithoutReports();
contact.reported_date = reportedDate;
// and
const config = {
c: contact,
targets: [ target ],
tasks: [],
};

// when
const emitted = loadLibWith(config).emitted;

// then
assert.deepEqual(emitted, [
{ _type:'target', date:reportedDate },
{ _type:'_complete', _id:true },
]);
});
it('should allow "now" as target date', function() {
// given
const target = aPersonBasedTarget();
target.date = 'now';
// and
const config = {
c: personWithoutReports(),
targets: [ target ],
tasks: [],
};

// when
const emitted = loadLibWith(config).emitted;

// then
assert.deepEqual(emitted, [
{ _type:'target', date:TEST_DATE },
Expand Down Expand Up @@ -584,3 +628,7 @@ describe('nools lib', function() {
return { contact:{ _id:`c-${idCounter}`, type:'clinic', reported_date:TEST_DATE }, reports };
}
});

function aRandomTimestamp() {
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
}

0 comments on commit aaa65ed

Please sign in to comment.