@outliant/sunrise-utils 1.1.8 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/helpers/sortScript.js +34 -1
- package/helpers/taskFilter/daysToComplete.js +220 -0
- package/helpers/taskFilter/index.js +20 -0
- package/lib/taskPipeline.js +55 -24
- package/package.json +1 -1
- package/test/helpers/taskFilter/daysToComplete.spec.js +160 -0
- package/test/lib/taskPipeline.spec.js +69 -56
package/CHANGELOG.md
CHANGED
|
@@ -4,13 +4,22 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [1.1.9](https://github.com/outliant/sunrise-utils/compare/1.1.8...1.1.9)
|
|
8
|
+
|
|
9
|
+
- Task/task new columns #85ztbmnkf [`#14`](https://github.com/outliant/sunrise-utils/pull/14)
|
|
10
|
+
- chore: add filter for days to complete [`f2fdf97`](https://github.com/outliant/sunrise-utils/commit/f2fdf977c6b5c5f22c17b3fffb7a6a2024a3c38c)
|
|
11
|
+
- chore: add test [`847deb3`](https://github.com/outliant/sunrise-utils/commit/847deb3d2eebba343b865bb69cb6dc642096160d)
|
|
12
|
+
- chore: fix test [`ad49d34`](https://github.com/outliant/sunrise-utils/commit/ad49d3451ff523426672528f42f65f77f2d05c5f)
|
|
13
|
+
|
|
7
14
|
#### [1.1.8](https://github.com/outliant/sunrise-utils/compare/1.1.7...1.1.8)
|
|
8
15
|
|
|
16
|
+
> 29 September 2023
|
|
17
|
+
|
|
9
18
|
- chore: use split string helper [`#13`](https://github.com/outliant/sunrise-utils/pull/13)
|
|
10
19
|
- chore: update logic for user pipeline [`#12`](https://github.com/outliant/sunrise-utils/pull/12)
|
|
20
|
+
- chore(release): 1.1.8 [`aa38c1a`](https://github.com/outliant/sunrise-utils/commit/aa38c1abac2d22fddb329fc18e071881b15837b3)
|
|
11
21
|
- chore: update users pipeline [`c0de2e6`](https://github.com/outliant/sunrise-utils/commit/c0de2e6bbacbeb1b8b96597473679f7f2424880e)
|
|
12
22
|
- chore: fix unit test [`84b880d`](https://github.com/outliant/sunrise-utils/commit/84b880d39497aa03257869702ecd0aa9f05b1d77)
|
|
13
|
-
- chore: fix test [`d7e1659`](https://github.com/outliant/sunrise-utils/commit/d7e1659d478e1787153deb0c6db79ebdf3105263)
|
|
14
23
|
|
|
15
24
|
#### [1.1.7](https://github.com/outliant/sunrise-utils/compare/1.1.6...1.1.7)
|
|
16
25
|
|
package/helpers/sortScript.js
CHANGED
|
@@ -210,7 +210,7 @@ module.exports.criticalPathStage = (order) => {
|
|
|
210
210
|
if (stageIndex != null) {
|
|
211
211
|
return stageIndex;
|
|
212
212
|
}
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
return 9999999;
|
|
215
215
|
} catch (Exception err) {
|
|
216
216
|
return 9999999;
|
|
@@ -318,6 +318,39 @@ module.exports.projectFieldNumeric = (order, value) => {
|
|
|
318
318
|
};
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
+
module.exports.daysToComplete = (order) => {
|
|
322
|
+
return {
|
|
323
|
+
_script: {
|
|
324
|
+
type: 'number',
|
|
325
|
+
script: {
|
|
326
|
+
lang: 'painless',
|
|
327
|
+
source: `
|
|
328
|
+
try {
|
|
329
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
330
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
331
|
+
|
|
332
|
+
if (isEmptyReadyAt || isEmptyCompletedAt) {
|
|
333
|
+
return -999999;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();
|
|
337
|
+
def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();
|
|
338
|
+
|
|
339
|
+
if (readyAt == null || completedAt == null) {
|
|
340
|
+
return -999999;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return completedAt - readyAt;
|
|
344
|
+
} catch (Exception err) {
|
|
345
|
+
return -999999;
|
|
346
|
+
}
|
|
347
|
+
`
|
|
348
|
+
},
|
|
349
|
+
order
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
|
|
321
354
|
module.exports.projectFieldText = (order, value) => {
|
|
322
355
|
return {
|
|
323
356
|
_script: {
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
|
|
3
|
+
const commonOperatorTemplate = (conditionCallback) => {
|
|
4
|
+
const condition = conditionCallback({
|
|
5
|
+
daysToComplete: 'daysToComplete',
|
|
6
|
+
value: 'params.value',
|
|
7
|
+
secondValue: 'params.second_value'
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
return `
|
|
11
|
+
try {
|
|
12
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
13
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
14
|
+
|
|
15
|
+
if (isEmptyReadyAt || isEmptyCompletedAt) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();
|
|
20
|
+
def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();
|
|
21
|
+
|
|
22
|
+
if (readyAt == null || completedAt == null) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);
|
|
27
|
+
|
|
28
|
+
return ${condition}
|
|
29
|
+
} catch (Exception err) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = (filter) => {
|
|
36
|
+
filter.value = _.parseInt(filter.value);
|
|
37
|
+
filter.second_value = _.parseInt(filter.second_value);
|
|
38
|
+
|
|
39
|
+
switch (filter.condition) {
|
|
40
|
+
case 'is_equal':
|
|
41
|
+
return module.exports.isEqual(filter);
|
|
42
|
+
case 'not_equal':
|
|
43
|
+
return module.exports.isNotEqual(filter);
|
|
44
|
+
case 'less_than':
|
|
45
|
+
return module.exports.lessThan(filter);
|
|
46
|
+
case 'less_than_or_equal':
|
|
47
|
+
return module.exports.lessThanOrEqual(filter);
|
|
48
|
+
case 'greater_than':
|
|
49
|
+
return module.exports.greaterThan(filter);
|
|
50
|
+
case 'greater_than_or_equal':
|
|
51
|
+
return module.exports.greaterThanOrEqual(filter);
|
|
52
|
+
case 'between':
|
|
53
|
+
return module.exports.between(filter);
|
|
54
|
+
case 'is_empty':
|
|
55
|
+
return module.exports.isEmpty(filter);
|
|
56
|
+
case 'is_not_empty':
|
|
57
|
+
return module.exports.isNotEmpty(filter);
|
|
58
|
+
default:
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
module.exports.isEqual = (filter) => {
|
|
64
|
+
return {
|
|
65
|
+
script: {
|
|
66
|
+
script: {
|
|
67
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
68
|
+
return `${daysToComplete} == ${value}`;
|
|
69
|
+
}),
|
|
70
|
+
lang: "painless",
|
|
71
|
+
params: {
|
|
72
|
+
value: filter.value,
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
module.exports.isNotEqual = (filter) => {
|
|
81
|
+
return {
|
|
82
|
+
script: {
|
|
83
|
+
script: {
|
|
84
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
85
|
+
return `${daysToComplete} != ${value}`;
|
|
86
|
+
}),
|
|
87
|
+
lang: "painless",
|
|
88
|
+
params: {
|
|
89
|
+
value: filter.value,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
module.exports.greaterThan = (filter) => {
|
|
98
|
+
return {
|
|
99
|
+
script: {
|
|
100
|
+
script: {
|
|
101
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
102
|
+
return `${daysToComplete} > ${value}`;
|
|
103
|
+
}),
|
|
104
|
+
lang: "painless",
|
|
105
|
+
params: {
|
|
106
|
+
value: filter.value,
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
module.exports.greaterThanOrEqual = (filter) => {
|
|
114
|
+
return {
|
|
115
|
+
script: {
|
|
116
|
+
script: {
|
|
117
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
118
|
+
return `${daysToComplete} >= ${value}`;
|
|
119
|
+
}),
|
|
120
|
+
lang: "painless",
|
|
121
|
+
params: {
|
|
122
|
+
value: filter.value,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
module.exports.lessThan = (filter) => {
|
|
130
|
+
return {
|
|
131
|
+
script: {
|
|
132
|
+
script: {
|
|
133
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
134
|
+
return `${daysToComplete} < ${value}`;
|
|
135
|
+
}),
|
|
136
|
+
lang: "painless",
|
|
137
|
+
params: {
|
|
138
|
+
value: filter.value,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
module.exports.lessThanOrEqual = (filter) => {
|
|
146
|
+
return {
|
|
147
|
+
script: {
|
|
148
|
+
script: {
|
|
149
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
150
|
+
return `${daysToComplete} <= ${value}`;
|
|
151
|
+
}),
|
|
152
|
+
lang: "painless",
|
|
153
|
+
params: {
|
|
154
|
+
value: filter.value,
|
|
155
|
+
second_value: filter.second_value
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
module.exports.between = (filter) => {
|
|
163
|
+
return {
|
|
164
|
+
script: {
|
|
165
|
+
script: {
|
|
166
|
+
source: commonOperatorTemplate(({ daysToComplete, value, secondValue }) => {
|
|
167
|
+
return `
|
|
168
|
+
${daysToComplete} >= ${value} &&
|
|
169
|
+
${daysToComplete} <= ${secondValue}
|
|
170
|
+
`;
|
|
171
|
+
}),
|
|
172
|
+
lang: "painless",
|
|
173
|
+
params: {
|
|
174
|
+
value: filter.value,
|
|
175
|
+
second_value: filter.second_value
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
module.exports.isEmpty = () => {
|
|
183
|
+
return {
|
|
184
|
+
script: {
|
|
185
|
+
script: {
|
|
186
|
+
source: `
|
|
187
|
+
try {
|
|
188
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
189
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
190
|
+
|
|
191
|
+
return isEmptyReadyAt || isEmptyCompletedAt;
|
|
192
|
+
} catch (Exception err) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
`,
|
|
196
|
+
lang: "painless"
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
module.exports.isNotEmpty = () => {
|
|
203
|
+
return {
|
|
204
|
+
script: {
|
|
205
|
+
script: {
|
|
206
|
+
source: `
|
|
207
|
+
try {
|
|
208
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
209
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
210
|
+
|
|
211
|
+
return !isEmptyReadyAt && !isEmptyCompletedAt;
|
|
212
|
+
} catch (Exception err) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
`,
|
|
216
|
+
lang: "painless"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
};
|
|
@@ -5,6 +5,7 @@ const buildRegionFilter = require('./regionFilter');
|
|
|
5
5
|
const buildTaskFieldFilter = require('./taskFieldFilter');
|
|
6
6
|
const buildCriticalPathFilter = require('./criticalPathFilter');
|
|
7
7
|
const buildOnHoldFilter = require('./onHoldFilter');
|
|
8
|
+
const buildDaysToCompleteFilter = require('./daysToComplete');
|
|
8
9
|
const buildAgeColorFilter = require('./buildAgeColorFilter');
|
|
9
10
|
const buildProjectFieldFilter = require('../projectFilter/projectFieldFilter');
|
|
10
11
|
const { PROJECT_BANNERS } = require('../../constants');
|
|
@@ -66,6 +67,18 @@ module.exports.defaultCustomColumns = [
|
|
|
66
67
|
type: 'ready_at',
|
|
67
68
|
field_type: 'date'
|
|
68
69
|
},
|
|
70
|
+
{
|
|
71
|
+
name: 'Days to Complete',
|
|
72
|
+
value: 'days_to_complete',
|
|
73
|
+
type: 'days_to_complete',
|
|
74
|
+
field_type: 'number'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'Pending Date',
|
|
78
|
+
value: 'pending_date',
|
|
79
|
+
type: 'pending_date',
|
|
80
|
+
field_type: 'date'
|
|
81
|
+
},
|
|
69
82
|
{
|
|
70
83
|
name: 'Project ID',
|
|
71
84
|
value: 'project_id',
|
|
@@ -222,11 +235,18 @@ module.exports.buildTaskPipelineFilter = (filter) => {
|
|
|
222
235
|
return buildCriticalPathFilter(filter);
|
|
223
236
|
case 'on_hold':
|
|
224
237
|
return buildOnHoldFilter(filter);
|
|
238
|
+
case 'days_to_complete':
|
|
239
|
+
return buildDaysToCompleteFilter(filter);
|
|
225
240
|
// Always expected as is_equal condition
|
|
226
241
|
case 'path_age':
|
|
227
242
|
return buildPathAgeFilter(filter);
|
|
228
243
|
case 'task_age':
|
|
229
244
|
return buildAgeColorFilter(filter);
|
|
245
|
+
case 'pending_date':
|
|
246
|
+
return buildTaskFieldFilter({
|
|
247
|
+
...filter,
|
|
248
|
+
type: 'ready_at'
|
|
249
|
+
});
|
|
230
250
|
// Always expected as is_equal condition with array of task template ids
|
|
231
251
|
case 'task_templates':
|
|
232
252
|
let value = filter.value;
|
package/lib/taskPipeline.js
CHANGED
|
@@ -98,30 +98,61 @@ class TaskPipeline {
|
|
|
98
98
|
} else {
|
|
99
99
|
sortByMultiple.forEach((s, i) => {
|
|
100
100
|
const sort = sortMultiple[i] || 'desc';
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
101
|
+
|
|
102
|
+
switch (true) {
|
|
103
|
+
case s === 'region':
|
|
104
|
+
taskPipelinesSort.push(sortScript.region(sort));
|
|
105
|
+
break;
|
|
106
|
+
|
|
107
|
+
case s === 'owner' :
|
|
108
|
+
case s === 'completed_by' :
|
|
109
|
+
taskPipelinesSort.push(sortScript.owner(sort));
|
|
110
|
+
break;
|
|
111
|
+
|
|
112
|
+
case s === 'status':
|
|
113
|
+
taskPipelinesSort.push(sortScript.status(sort));
|
|
114
|
+
break;
|
|
115
|
+
|
|
116
|
+
case s === 'critical_path_stage':
|
|
117
|
+
taskPipelinesSort.push(sortScript.criticalPathStage(sort));
|
|
118
|
+
break;
|
|
119
|
+
|
|
120
|
+
case s === 'project_id':
|
|
121
|
+
taskPipelinesSort.push(sortScript.projectId(sort));
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case s === 'ready_at':
|
|
125
|
+
taskPipelinesSort.push(sortScript.readyAt(sort));
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case s === 'pending_date':
|
|
129
|
+
taskPipelinesSort.push({
|
|
130
|
+
ready_at: { order: sort, missing: '_last' }
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
|
|
134
|
+
case s === 'days_to_complete':
|
|
135
|
+
taskPipelinesSort.push(sortScript.daysToComplete(sort));
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
case s === 'was_marked_incomplete':
|
|
139
|
+
taskPipelinesSort.push(sortScript.wasMarkedIncomplete(sort));
|
|
140
|
+
break;
|
|
141
|
+
|
|
142
|
+
case s === 'last_comment_date':
|
|
143
|
+
taskPipelinesSort.push(sortScript.lastCommentDate(sort));
|
|
144
|
+
break;
|
|
145
|
+
|
|
146
|
+
case isUuid(s):
|
|
147
|
+
taskPipelinesSort.push(sortScript.projectFieldNumeric(sort, s));
|
|
148
|
+
taskPipelinesSort.push(sortScript.projectFieldText(sort, s));
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
default:
|
|
152
|
+
taskPipelinesSort.push({
|
|
153
|
+
[s]: { order: sort, missing: '_last' }
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
125
156
|
}
|
|
126
157
|
});
|
|
127
158
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/* eslint-env node, mocha */
|
|
4
|
+
const { expect } = require('chai');
|
|
5
|
+
|
|
6
|
+
// To test
|
|
7
|
+
const daysToComplete = require('../../../helpers/taskFilter/daysToComplete');
|
|
8
|
+
|
|
9
|
+
describe('taskFilter/daysToComplete', function () {
|
|
10
|
+
const commonInput = {
|
|
11
|
+
field_id: '',
|
|
12
|
+
type: 'days_to_complete',
|
|
13
|
+
field_type: 'number',
|
|
14
|
+
value: 1,
|
|
15
|
+
second_value: 5
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const filters = [
|
|
19
|
+
{
|
|
20
|
+
input: {
|
|
21
|
+
...commonInput,
|
|
22
|
+
condition: 'not_equal'
|
|
23
|
+
},
|
|
24
|
+
expected: {
|
|
25
|
+
script: {
|
|
26
|
+
script: {
|
|
27
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete != params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
28
|
+
lang: "painless",
|
|
29
|
+
params: {
|
|
30
|
+
value: 1
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
input: {
|
|
38
|
+
...commonInput,
|
|
39
|
+
condition: 'less_than'
|
|
40
|
+
},
|
|
41
|
+
expected: {
|
|
42
|
+
script: {
|
|
43
|
+
script: {
|
|
44
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete < params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
45
|
+
lang: "painless",
|
|
46
|
+
params: {
|
|
47
|
+
value: 1
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
input: {
|
|
55
|
+
...commonInput,
|
|
56
|
+
condition: 'less_than_or_equal'
|
|
57
|
+
},
|
|
58
|
+
expected: {
|
|
59
|
+
script: {
|
|
60
|
+
script: {
|
|
61
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete <= params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
62
|
+
lang: "painless",
|
|
63
|
+
params: {
|
|
64
|
+
value: 1,
|
|
65
|
+
second_value: 5
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
input: {
|
|
73
|
+
...commonInput,
|
|
74
|
+
condition: 'greater_than'
|
|
75
|
+
},
|
|
76
|
+
expected: {
|
|
77
|
+
script: {
|
|
78
|
+
script: {
|
|
79
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete > params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
80
|
+
lang: "painless",
|
|
81
|
+
params: {
|
|
82
|
+
value: 1
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
input: {
|
|
90
|
+
...commonInput,
|
|
91
|
+
condition: 'greater_than_or_equal'
|
|
92
|
+
},
|
|
93
|
+
expected: {
|
|
94
|
+
script: {
|
|
95
|
+
script: {
|
|
96
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete >= params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
97
|
+
lang: "painless",
|
|
98
|
+
params: {
|
|
99
|
+
value: 1
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
input: {
|
|
107
|
+
...commonInput,
|
|
108
|
+
condition: 'between'
|
|
109
|
+
},
|
|
110
|
+
expected: {
|
|
111
|
+
script: {
|
|
112
|
+
script: {
|
|
113
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return \n daysToComplete >= params.value &&\n daysToComplete <= params.second_value\n \n } catch (Exception err) {\n return false;\n }\n ",
|
|
114
|
+
lang: "painless",
|
|
115
|
+
params: {
|
|
116
|
+
value: 1,
|
|
117
|
+
second_value: 5
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
input: {
|
|
125
|
+
...commonInput,
|
|
126
|
+
condition: 'is_empty'
|
|
127
|
+
},
|
|
128
|
+
expected: {
|
|
129
|
+
script: {
|
|
130
|
+
script: {
|
|
131
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n return isEmptyReadyAt || isEmptyCompletedAt;\n } catch (Exception err) {\n return false;\n }\n ",
|
|
132
|
+
lang: "painless"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
input: {
|
|
139
|
+
...commonInput,
|
|
140
|
+
condition: 'is_not_empty'
|
|
141
|
+
},
|
|
142
|
+
expected: {
|
|
143
|
+
script: {
|
|
144
|
+
script: {
|
|
145
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n return !isEmptyReadyAt && !isEmptyCompletedAt;\n } catch (Exception err) {\n return false;\n }\n ",
|
|
146
|
+
lang: "painless"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
filters.forEach((filter) => {
|
|
154
|
+
it(filter.input.condition, (done) => {
|
|
155
|
+
expect(daysToComplete(filter.input)).to.deep.equal(filter.expected);
|
|
156
|
+
|
|
157
|
+
done();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -257,123 +257,136 @@ describe('taskPipeline', function () {
|
|
|
257
257
|
}
|
|
258
258
|
]
|
|
259
259
|
);
|
|
260
|
+
|
|
260
261
|
expect(sort).to.deep.equal([
|
|
261
262
|
{
|
|
262
263
|
_script: {
|
|
263
|
-
type:
|
|
264
|
+
type: "number",
|
|
264
265
|
script: {
|
|
265
|
-
lang:
|
|
266
|
-
source:
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
lang: "painless",
|
|
267
|
+
source: "\n if (params.starredTaskIds.contains(doc._id.value)) {\n return 1;\n } else {\n return 0;\n }\n ",
|
|
268
|
+
params: {
|
|
269
|
+
starredTaskIds: [
|
|
270
|
+
"task-1",
|
|
271
|
+
"task-2"
|
|
272
|
+
]
|
|
273
|
+
}
|
|
269
274
|
},
|
|
270
|
-
order:
|
|
275
|
+
order: "desc"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
region_name: {
|
|
280
|
+
order: "asc"
|
|
271
281
|
}
|
|
272
282
|
},
|
|
273
|
-
{ region_name: { order: 'asc' } },
|
|
274
283
|
{
|
|
275
284
|
_script: {
|
|
276
|
-
type:
|
|
285
|
+
type: "string",
|
|
277
286
|
script: {
|
|
278
|
-
lang:
|
|
279
|
-
source:
|
|
280
|
-
"\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
287
|
+
lang: "painless",
|
|
288
|
+
source: "\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
281
289
|
},
|
|
282
|
-
order:
|
|
290
|
+
order: "asc"
|
|
283
291
|
}
|
|
284
292
|
},
|
|
285
293
|
{
|
|
286
294
|
_script: {
|
|
287
|
-
type:
|
|
295
|
+
type: "string",
|
|
288
296
|
script: {
|
|
289
|
-
lang:
|
|
290
|
-
source:
|
|
291
|
-
"\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
297
|
+
lang: "painless",
|
|
298
|
+
source: "\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
292
299
|
},
|
|
293
|
-
order:
|
|
300
|
+
order: "asc"
|
|
294
301
|
}
|
|
295
302
|
},
|
|
296
303
|
{
|
|
297
304
|
_script: {
|
|
298
|
-
type:
|
|
305
|
+
type: "string",
|
|
299
306
|
script: {
|
|
300
|
-
lang:
|
|
301
|
-
source:
|
|
302
|
-
"\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true) {\n if (isComplete == true) {\n return 'completed';\n }\n\n return 'pending';\n }\n\n return 'new';\n } catch (Exception err) {\n return '';\n }\n "
|
|
307
|
+
lang: "painless",
|
|
308
|
+
source: "\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true) {\n if (isComplete == true) {\n return 'completed';\n }\n\n return 'pending';\n }\n\n return 'new';\n } catch (Exception err) {\n return '';\n }\n "
|
|
303
309
|
},
|
|
304
|
-
order:
|
|
310
|
+
order: "desc"
|
|
305
311
|
}
|
|
306
312
|
},
|
|
307
313
|
{
|
|
308
314
|
_script: {
|
|
309
|
-
type:
|
|
315
|
+
type: "number",
|
|
310
316
|
script: {
|
|
311
|
-
lang:
|
|
312
|
-
source:
|
|
313
|
-
"\n try {\n def stageIndex = doc['critical_path.stage_index'].value;\n if (stageIndex != null) {\n return stageIndex;\n }\n \n return 9999999;\n } catch (Exception err) {\n return 9999999;\n }\n "
|
|
317
|
+
lang: "painless",
|
|
318
|
+
source: "\n try {\n def stageIndex = doc['critical_path.stage_index'].value;\n if (stageIndex != null) {\n return stageIndex;\n }\n\n return 9999999;\n } catch (Exception err) {\n return 9999999;\n }\n "
|
|
314
319
|
},
|
|
315
|
-
order:
|
|
320
|
+
order: "desc"
|
|
316
321
|
}
|
|
317
322
|
},
|
|
318
323
|
{
|
|
319
324
|
_script: {
|
|
320
|
-
type:
|
|
325
|
+
type: "number",
|
|
321
326
|
script: {
|
|
322
|
-
lang:
|
|
323
|
-
source:
|
|
324
|
-
"\n def projectNumber = params._source.project_id;\n projectNumber = /[^0-9]/.matcher(projectNumber).replaceAll('');\n return Integer.parseInt(projectNumber);\n "
|
|
327
|
+
lang: "painless",
|
|
328
|
+
source: "\n def projectNumber = params._source.project_id;\n projectNumber = /[^0-9]/.matcher(projectNumber).replaceAll('');\n return Integer.parseInt(projectNumber);\n "
|
|
325
329
|
},
|
|
326
|
-
order:
|
|
330
|
+
order: "desc"
|
|
327
331
|
}
|
|
328
332
|
},
|
|
329
333
|
{
|
|
330
334
|
_script: {
|
|
331
|
-
type:
|
|
335
|
+
type: "number",
|
|
332
336
|
script: {
|
|
333
|
-
lang:
|
|
334
|
-
source:
|
|
335
|
-
"\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true && isComplete == true && doc.containsKey('completed_at') && !doc['completed_at'].empty) {\n return doc['completed_at'].value.millis;\n } else if (isReady == true && doc.containsKey('ready_at') && !doc['ready_at'].empty) {\n return doc['ready_at'].value.millis;\n }\n\n return doc['created_at'].value.millis;\n } catch (Exception err) {\n return 0;\n }\n "
|
|
337
|
+
lang: "painless",
|
|
338
|
+
source: "\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true && isComplete == true && doc.containsKey('completed_at') && !doc['completed_at'].empty) {\n return doc['completed_at'].value.millis;\n } else if (isReady == true && doc.containsKey('ready_at') && !doc['ready_at'].empty) {\n return doc['ready_at'].value.millis;\n }\n\n return doc['created_at'].value.millis;\n } catch (Exception err) {\n return 0;\n }\n "
|
|
336
339
|
},
|
|
337
|
-
order:
|
|
340
|
+
order: "desc"
|
|
338
341
|
}
|
|
339
342
|
},
|
|
340
343
|
{
|
|
341
344
|
_script: {
|
|
342
|
-
type:
|
|
345
|
+
type: "number",
|
|
343
346
|
script: {
|
|
344
|
-
lang:
|
|
345
|
-
source:
|
|
346
|
-
"\n return doc['was_marked_incomplete'].empty\n ? 0\n : doc['was_marked_incomplete'].value ? 1 : 0;\n "
|
|
347
|
+
lang: "painless",
|
|
348
|
+
source: "\n return doc['was_marked_incomplete'].empty\n ? 0\n : doc['was_marked_incomplete'].value ? 1 : 0;\n "
|
|
347
349
|
},
|
|
348
|
-
order:
|
|
350
|
+
order: "desc"
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"last_comment_data.created_at": {
|
|
355
|
+
order: "desc"
|
|
349
356
|
}
|
|
350
357
|
},
|
|
351
|
-
{ 'last_comment_data.created_at': { order: 'desc' } },
|
|
352
358
|
{
|
|
353
359
|
_script: {
|
|
354
|
-
type:
|
|
360
|
+
type: "number",
|
|
355
361
|
script: {
|
|
356
|
-
lang:
|
|
357
|
-
source:
|
|
358
|
-
|
|
359
|
-
|
|
362
|
+
lang: "painless",
|
|
363
|
+
source: "\n try {\n def fields = params._source.fields;\n\n for (int i=0; i<fields.size(); i++) {\n if (fields[i].id.equals(params.value)) {\n if (fields[i].number != null) {\n return fields[i].number;\n } else {\n return -999999;\n }\n }\n }\n\n return -999999;\n } catch (Exception err) {\n return -999999;\n }\n ",
|
|
364
|
+
params: {
|
|
365
|
+
value: "38d423bf-fc24-4183-b8b7-15420c89e318"
|
|
366
|
+
}
|
|
360
367
|
},
|
|
361
|
-
order:
|
|
368
|
+
order: "desc"
|
|
362
369
|
}
|
|
363
370
|
},
|
|
364
371
|
{
|
|
365
372
|
_script: {
|
|
366
|
-
type:
|
|
373
|
+
type: "string",
|
|
367
374
|
script: {
|
|
368
|
-
lang:
|
|
369
|
-
source:
|
|
370
|
-
|
|
371
|
-
|
|
375
|
+
lang: "painless",
|
|
376
|
+
source: "\n try {\n String textInfo = '';\n def fields = params._source.fields;\n\n for (int i=0; i<fields.size(); i++) {\n if (fields[i].id.equals(params.value)) {\n\n if (fields[i].number != null) {\n return '';\n }\n\n textInfo = fields[i].text == null ? '' : fields[i].text;\n if (fields[i].containsKey('computedText')) {\n textInfo = fields[i].computedText == null ? textInfo : fields[i].computedText;\n }\n }\n }\n\n return textInfo;\n } catch (Exception err) {\n return '';\n }\n ",
|
|
377
|
+
params: {
|
|
378
|
+
value: "38d423bf-fc24-4183-b8b7-15420c89e318"
|
|
379
|
+
}
|
|
372
380
|
},
|
|
373
|
-
order:
|
|
381
|
+
order: "desc"
|
|
374
382
|
}
|
|
375
383
|
},
|
|
376
|
-
{
|
|
384
|
+
{
|
|
385
|
+
id: {
|
|
386
|
+
order: "desc",
|
|
387
|
+
missing: "_last"
|
|
388
|
+
}
|
|
389
|
+
}
|
|
377
390
|
]);
|
|
378
391
|
done();
|
|
379
392
|
});
|