@outliant/sunrise-utils 1.1.25 → 1.1.26

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 CHANGED
@@ -4,8 +4,16 @@ 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.26](https://github.com/outliant/sunrise-utils/compare/1.1.25...1.1.26)
8
+
9
+ - project critical path age column with sort and filter [`#34`](https://github.com/outliant/sunrise-utils/pull/34)
10
+ - unit test [`72423f0`](https://github.com/outliant/sunrise-utils/commit/72423f0178f7b17d7c667675cf1ec96afe19002f)
11
+
7
12
  #### [1.1.25](https://github.com/outliant/sunrise-utils/compare/1.1.24...1.1.25)
8
13
 
14
+ > 19 March 2024
15
+
16
+ - chore(release): 1.1.25 [`80c44dd`](https://github.com/outliant/sunrise-utils/commit/80c44dd35a588f0121d8807deedfc62cc9f2934c)
9
17
  - chore: added project-pipeline criticalPathAge column #86azmbay5 [`5c9c9a2`](https://github.com/outliant/sunrise-utils/commit/5c9c9a216d926a2451216bbb1337d446ead9a93c)
10
18
 
11
19
  #### [1.1.24](https://github.com/outliant/sunrise-utils/compare/1.1.23...1.1.24)
@@ -0,0 +1,205 @@
1
+ const _ = require('lodash');
2
+
3
+ const criticalPathAgeFilterScript = `
4
+ try {
5
+ if (doc.containsKey('critical_path.date_added') && !doc['critical_path.date_added'].empty) {
6
+ def now = new Date().getTime();
7
+ def dateAdded = doc['critical_path.date_added'].value.millis;
8
+ double ageDays = Math.floor((now - dateAdded)/(1000 * 3600 * 24));
9
+
10
+ if (params.condition == 'isEqual') {
11
+ return ageDays == params.value;
12
+ } else if (params.condition == 'notEqual') {
13
+ return ageDays != params.value;
14
+ } else if (params.condition == 'lessThan') {
15
+ return ageDays < params.value;
16
+ } else if (params.condition == 'lessThanOrEqual') {
17
+ return ageDays <= params.value;
18
+ } else if (params.condition == 'greaterThan') {
19
+ return ageDays > params.value;
20
+ } else if (params.condition == 'greaterThanOrEqual') {
21
+ return ageDays >= params.value;
22
+ } else if (params.condition == 'between') {
23
+ return ageDays > params.value && ageDays < params.second_value;
24
+ }
25
+
26
+ return false;
27
+ }
28
+
29
+ return false;
30
+ } catch(Exception err){
31
+ return false;
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: criticalPathAgeFilterScript,
68
+ lang: 'painless',
69
+ params: {
70
+ value: filter.value,
71
+ condition: 'isEqual'
72
+ }
73
+ }
74
+ }
75
+ };
76
+ };
77
+
78
+ module.exports.isNotEqual = (filter) => {
79
+ return {
80
+ script: {
81
+ script: {
82
+ source: criticalPathAgeFilterScript,
83
+ lang: 'painless',
84
+ params: {
85
+ value: filter.value,
86
+ condition: 'notEqual'
87
+ }
88
+ }
89
+ }
90
+ };
91
+ };
92
+
93
+ module.exports.lessThan = (filter) => {
94
+ return {
95
+ script: {
96
+ script: {
97
+ source: criticalPathAgeFilterScript,
98
+ lang: 'painless',
99
+ params: {
100
+ value: filter.value,
101
+ condition: 'lessThan'
102
+ }
103
+ }
104
+ }
105
+ };
106
+ };
107
+
108
+ module.exports.lessThanOrEqual = (filter) => {
109
+ return {
110
+ script: {
111
+ script: {
112
+ source: criticalPathAgeFilterScript,
113
+ lang: 'painless',
114
+ params: {
115
+ value: filter.value,
116
+ condition: 'lessThanOrEqual'
117
+ }
118
+ }
119
+ }
120
+ };
121
+ };
122
+
123
+ module.exports.greaterThan = (filter) => {
124
+ return {
125
+ script: {
126
+ script: {
127
+ source: criticalPathAgeFilterScript,
128
+ lang: 'painless',
129
+ params: {
130
+ value: filter.value,
131
+ condition: 'greaterThan'
132
+ }
133
+ }
134
+ }
135
+ };
136
+ };
137
+
138
+ module.exports.greaterThanOrEqual = (filter) => {
139
+ return {
140
+ script: {
141
+ script: {
142
+ source: criticalPathAgeFilterScript,
143
+ lang: 'painless',
144
+ params: {
145
+ value: filter.value,
146
+ condition: 'greaterThanOrEqual'
147
+ }
148
+ }
149
+ }
150
+ };
151
+ };
152
+
153
+ module.exports.between = (filter) => {
154
+ return {
155
+ script: {
156
+ script: {
157
+ source: criticalPathAgeFilterScript,
158
+ lang: 'painless',
159
+ params: {
160
+ value: filter.value,
161
+ second_value: filter.second_value,
162
+ condition: 'between'
163
+ }
164
+ }
165
+ }
166
+ };
167
+ };
168
+
169
+ module.exports.isEmpty = () => {
170
+ return {
171
+ script: {
172
+ script: {
173
+ source: `
174
+ try {
175
+ def notEmpty = doc.containsKey('critical_path.date_added') && !doc['critical_path.date_added'].empty;
176
+
177
+ return !notEmpty
178
+ } catch (Exception err) {
179
+ return false;
180
+ }
181
+ `,
182
+ lang: 'painless'
183
+ }
184
+ }
185
+ };
186
+ };
187
+
188
+ module.exports.isNotEmpty = () => {
189
+ return {
190
+ script: {
191
+ script: {
192
+ source: `
193
+ try {
194
+ def notEmpty = doc.containsKey('critical_path.date_added') && !doc['critical_path.date_added'].empty;
195
+
196
+ return notEmpty
197
+ } catch (Exception err) {
198
+ return false;
199
+ }
200
+ `,
201
+ lang: 'painless'
202
+ }
203
+ }
204
+ };
205
+ };
@@ -1,5 +1,6 @@
1
1
  const buildRegionFilter = require('./regionFilter');
2
2
  const buildCriticalPathFilter = require('./criticalPathFilter');
3
+ const buildCriticalPathAgeFilter = require('./criticalPathAgeFilter');
3
4
  const buildOnHoldFilter = require('./onHoldFilter');
4
5
  const buildIsPausedFilter = require('./isPausedFilter');
5
6
  const buildIsGeneratedFilter = require('./isGeneratedFilter');
@@ -31,7 +32,7 @@ module.exports.defaultCustomColumns = [
31
32
  name: 'Critical Path Age',
32
33
  value: 'criticalPathAge',
33
34
  type: 'criticalPathAge',
34
- field_type: 'date'
35
+ field_type: 'number'
35
36
  },
36
37
  {
37
38
  name: 'Cancelled',
@@ -131,6 +132,8 @@ module.exports.buildProjectPipelineFilter = (filter) => {
131
132
  return buildRegionFilter(filter);
132
133
  case 'criticalPathStage':
133
134
  return buildCriticalPathFilter(filter);
135
+ case 'criticalPathAge':
136
+ return buildCriticalPathAgeFilter(filter);
134
137
  case 'on_hold':
135
138
  return buildOnHoldFilter(filter);
136
139
  case 'is_paused':
@@ -222,6 +222,14 @@ module.exports.criticalPathStage = (order) => {
222
222
  };
223
223
  };
224
224
 
225
+ module.exports.criticalPathAge = (order) => {
226
+ return {
227
+ 'critical_path.date_added': {
228
+ order
229
+ }
230
+ };
231
+ };
232
+
225
233
  module.exports.isPaused = (order) => {
226
234
  return {
227
235
  _script: {
@@ -51,7 +51,7 @@ class ProjectPipeline {
51
51
  }
52
52
 
53
53
  if (query.projectIds && query.projectIds.length) {
54
- const should = query.projectIds.map(projectId => {
54
+ const should = query.projectIds.map((projectId) => {
55
55
  return {
56
56
  match: {
57
57
  _id: projectId
@@ -106,6 +106,10 @@ class ProjectPipeline {
106
106
  projectPipelinesSort.push(sortScript.criticalPathStage(sort));
107
107
  break;
108
108
 
109
+ case s === 'criticalPathAge':
110
+ projectPipelinesSort.push(sortScript.criticalPathAge(sort));
111
+ break;
112
+
109
113
  case s === 'is_paused':
110
114
  projectPipelinesSort.push(sortScript.isPaused(sort));
111
115
  break;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@outliant/sunrise-utils",
3
3
  "description": "Helper functions for project Sunrise",
4
- "version": "1.1.25",
4
+ "version": "1.1.26",
5
5
  "license": "ISC",
6
6
  "author": "Outliant",
7
7
  "main": "index.js",
@@ -8,6 +8,7 @@ const moment = require('moment');
8
8
  // To test
9
9
  const projectFieldFilter = require('../../../helpers/projectFilter/projectFieldFilter');
10
10
  const projectFilter = require('../../../helpers/projectFilter/projectFilter');
11
+ const criticalPathAgeFilter = require('../../../helpers/projectFilter/criticalPathAgeFilter');
11
12
 
12
13
  describe('projectFilter/projectFieldFilter', function () {
13
14
  const filters = [
@@ -166,7 +167,13 @@ describe('projectFilter/projectFieldFilter', function () {
166
167
  query: {
167
168
  bool: {
168
169
  must: [
169
- { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
170
+ {
171
+ term: {
172
+ 'fields.id': {
173
+ value: '2726455e-fd84-4049-9756-e981e20a8772'
174
+ }
175
+ }
176
+ },
170
177
  { term: { 'fields.text': { value: 'Commercial' } } }
171
178
  ]
172
179
  }
@@ -185,7 +192,13 @@ describe('projectFilter/projectFieldFilter', function () {
185
192
  query: {
186
193
  bool: {
187
194
  must: [
188
- { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
195
+ {
196
+ term: {
197
+ 'fields.id': {
198
+ value: '2726455e-fd84-4049-9756-e981e20a8772'
199
+ }
200
+ }
201
+ },
189
202
  { term: { 'fields.text': { value: 'Hanwha' } } }
190
203
  ]
191
204
  }
@@ -249,7 +262,13 @@ describe('projectFilter/projectFieldFilter', function () {
249
262
  query: {
250
263
  bool: {
251
264
  must: [
252
- { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
265
+ {
266
+ term: {
267
+ 'fields.id': {
268
+ value: '2726455e-fd84-4049-9756-e981e20a8772'
269
+ }
270
+ }
271
+ },
253
272
  { term: { 'fields.text': { value: 'Commercial' } } }
254
273
  ]
255
274
  }
@@ -268,7 +287,13 @@ describe('projectFilter/projectFieldFilter', function () {
268
287
  query: {
269
288
  bool: {
270
289
  must: [
271
- { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
290
+ {
291
+ term: {
292
+ 'fields.id': {
293
+ value: '2726455e-fd84-4049-9756-e981e20a8772'
294
+ }
295
+ }
296
+ },
272
297
  { term: { 'fields.text': { value: 'Hanwha' } } }
273
298
  ]
274
299
  }
@@ -303,7 +328,13 @@ describe('projectFilter/projectFieldFilter', function () {
303
328
  query: {
304
329
  bool: {
305
330
  must: [
306
- { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
331
+ {
332
+ term: {
333
+ 'fields.id': {
334
+ value: '2726455e-fd84-4049-9756-e981e20a8772'
335
+ }
336
+ }
337
+ },
307
338
  { term: { 'fields.text': { value: 'Hanwha' } } }
308
339
  ]
309
340
  }
@@ -1087,7 +1118,7 @@ describe('projectFilter/projectFilter', () => {
1087
1118
  }
1088
1119
  }
1089
1120
  },
1090
- ...['before', 'less_than'].map(condition => ({
1121
+ ...['before', 'less_than'].map((condition) => ({
1091
1122
  input: {
1092
1123
  condition: condition,
1093
1124
  field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
@@ -1110,7 +1141,7 @@ describe('projectFilter/projectFilter', () => {
1110
1141
  }
1111
1142
  }
1112
1143
  })),
1113
- ...['after', 'greater_than'].map(condition => ({
1144
+ ...['after', 'greater_than'].map((condition) => ({
1114
1145
  input: {
1115
1146
  condition: condition,
1116
1147
  field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
@@ -1172,13 +1203,8 @@ describe('projectFilter/projectFilter', () => {
1172
1203
  {
1173
1204
  range: {
1174
1205
  created_at: {
1175
- gt: moment()
1176
- .startOf('day')
1177
- .valueOf(),
1178
- lt: moment()
1179
- .add(5, 'd')
1180
- .endOf('day')
1181
- .valueOf()
1206
+ gt: moment().startOf('day').valueOf(),
1207
+ lt: moment().add(5, 'd').endOf('day').valueOf()
1182
1208
  }
1183
1209
  }
1184
1210
  }
@@ -1201,13 +1227,8 @@ describe('projectFilter/projectFilter', () => {
1201
1227
  {
1202
1228
  range: {
1203
1229
  created_at: {
1204
- lt: moment()
1205
- .startOf('day')
1206
- .valueOf(),
1207
- gt: moment()
1208
- .subtract(3, 'd')
1209
- .endOf('day')
1210
- .valueOf()
1230
+ lt: moment().startOf('day').valueOf(),
1231
+ gt: moment().subtract(3, 'd').endOf('day').valueOf()
1211
1232
  }
1212
1233
  }
1213
1234
  }
@@ -1230,7 +1251,7 @@ describe('projectFilter/projectFilter', () => {
1230
1251
  {
1231
1252
  term: {
1232
1253
  created_at: {
1233
- value: ""
1254
+ value: ''
1234
1255
  }
1235
1256
  }
1236
1257
  },
@@ -1239,7 +1260,7 @@ describe('projectFilter/projectFilter', () => {
1239
1260
  must_not: [
1240
1261
  {
1241
1262
  exists: {
1242
- field: "created_at"
1263
+ field: 'created_at'
1243
1264
  }
1244
1265
  }
1245
1266
  ]
@@ -1264,7 +1285,7 @@ describe('projectFilter/projectFilter', () => {
1264
1285
  {
1265
1286
  term: {
1266
1287
  created_at: {
1267
- value: ""
1288
+ value: ''
1268
1289
  }
1269
1290
  }
1270
1291
  }
@@ -1272,7 +1293,7 @@ describe('projectFilter/projectFilter', () => {
1272
1293
  must: [
1273
1294
  {
1274
1295
  exists: {
1275
- field: "created_at"
1296
+ field: 'created_at'
1276
1297
  }
1277
1298
  }
1278
1299
  ]
@@ -1291,4 +1312,215 @@ describe('projectFilter/projectFilter', () => {
1291
1312
  done();
1292
1313
  });
1293
1314
  });
1294
- });
1315
+ });
1316
+
1317
+ describe('projectFilter/criticalPathAgeFilter', () => {
1318
+ const criticalPathAgeFilterScript = `
1319
+ try {
1320
+ if (doc.containsKey('critical_path.date_added') && !doc['critical_path.date_added'].empty) {
1321
+ def now = new Date().getTime();
1322
+ def dateAdded = doc['critical_path.date_added'].value.millis;
1323
+ double ageDays = Math.floor((now - dateAdded)/(1000 * 3600 * 24));
1324
+
1325
+ if (params.condition == 'isEqual') {
1326
+ return ageDays == params.value;
1327
+ } else if (params.condition == 'notEqual') {
1328
+ return ageDays != params.value;
1329
+ } else if (params.condition == 'lessThan') {
1330
+ return ageDays < params.value;
1331
+ } else if (params.condition == 'lessThanOrEqual') {
1332
+ return ageDays <= params.value;
1333
+ } else if (params.condition == 'greaterThan') {
1334
+ return ageDays > params.value;
1335
+ } else if (params.condition == 'greaterThanOrEqual') {
1336
+ return ageDays >= params.value;
1337
+ } else if (params.condition == 'between') {
1338
+ return ageDays > params.value && ageDays < params.second_value;
1339
+ }
1340
+
1341
+ return false;
1342
+ }
1343
+
1344
+ return false;
1345
+ } catch(Exception err){
1346
+ return false;
1347
+ }
1348
+ `;
1349
+
1350
+ const commonInput = {
1351
+ field_id: '',
1352
+ type: 'criticalPathAge',
1353
+ field_type: 'number',
1354
+ value: 6,
1355
+ second_value: 20
1356
+ };
1357
+
1358
+ const filters = [
1359
+ {
1360
+ input: {
1361
+ ...commonInput,
1362
+ condition: 'is_equal'
1363
+ },
1364
+ output: {
1365
+ script: {
1366
+ script: {
1367
+ source: criticalPathAgeFilterScript,
1368
+ lang: 'painless',
1369
+ params: {
1370
+ value: 6,
1371
+ condition: 'isEqual'
1372
+ }
1373
+ }
1374
+ }
1375
+ }
1376
+ },
1377
+ {
1378
+ input: {
1379
+ ...commonInput,
1380
+ condition: 'not_equal'
1381
+ },
1382
+ output: {
1383
+ script: {
1384
+ script: {
1385
+ source: criticalPathAgeFilterScript,
1386
+ lang: 'painless',
1387
+ params: {
1388
+ value: 6,
1389
+ condition: 'notEqual'
1390
+ }
1391
+ }
1392
+ }
1393
+ }
1394
+ },
1395
+ {
1396
+ input: {
1397
+ ...commonInput,
1398
+ condition: 'less_than'
1399
+ },
1400
+ output: {
1401
+ script: {
1402
+ script: {
1403
+ source: criticalPathAgeFilterScript,
1404
+ lang: 'painless',
1405
+ params: {
1406
+ value: 6,
1407
+ condition: 'lessThan'
1408
+ }
1409
+ }
1410
+ }
1411
+ }
1412
+ },
1413
+ {
1414
+ input: {
1415
+ ...commonInput,
1416
+ condition: 'less_than_or_equal'
1417
+ },
1418
+ output: {
1419
+ script: {
1420
+ script: {
1421
+ source: criticalPathAgeFilterScript,
1422
+ lang: 'painless',
1423
+ params: {
1424
+ value: 6,
1425
+ condition: 'lessThanOrEqual'
1426
+ }
1427
+ }
1428
+ }
1429
+ }
1430
+ },
1431
+ {
1432
+ input: {
1433
+ ...commonInput,
1434
+ condition: 'greater_than'
1435
+ },
1436
+ output: {
1437
+ script: {
1438
+ script: {
1439
+ source: criticalPathAgeFilterScript,
1440
+ lang: 'painless',
1441
+ params: {
1442
+ value: 6,
1443
+ condition: 'greaterThan'
1444
+ }
1445
+ }
1446
+ }
1447
+ }
1448
+ },
1449
+ {
1450
+ input: {
1451
+ ...commonInput,
1452
+ condition: 'greater_than_or_equal'
1453
+ },
1454
+ output: {
1455
+ script: {
1456
+ script: {
1457
+ source: criticalPathAgeFilterScript,
1458
+ lang: 'painless',
1459
+ params: {
1460
+ value: 6,
1461
+ condition: 'greaterThanOrEqual'
1462
+ }
1463
+ }
1464
+ }
1465
+ }
1466
+ },
1467
+ {
1468
+ input: {
1469
+ ...commonInput,
1470
+ condition: 'between'
1471
+ },
1472
+ output: {
1473
+ script: {
1474
+ script: {
1475
+ source: criticalPathAgeFilterScript,
1476
+ lang: 'painless',
1477
+ params: {
1478
+ value: 6,
1479
+ second_value: 20,
1480
+ condition: 'between'
1481
+ }
1482
+ }
1483
+ }
1484
+ }
1485
+ },
1486
+ {
1487
+ input: {
1488
+ ...commonInput,
1489
+ condition: 'is_empty'
1490
+ },
1491
+ output: {
1492
+ script: {
1493
+ script: {
1494
+ source:
1495
+ "\n try {\n def notEmpty = doc.containsKey('critical_path.date_added') && !doc['critical_path.date_added'].empty;\n\n return !notEmpty\n } catch (Exception err) {\n return false;\n }\n ",
1496
+ lang: 'painless'
1497
+ }
1498
+ }
1499
+ }
1500
+ },
1501
+ {
1502
+ input: {
1503
+ ...commonInput,
1504
+ condition: 'is_not_empty'
1505
+ },
1506
+ output: {
1507
+ script: {
1508
+ script: {
1509
+ source:
1510
+ "\n try {\n def notEmpty = doc.containsKey('critical_path.date_added') && !doc['critical_path.date_added'].empty;\n\n return notEmpty\n } catch (Exception err) {\n return false;\n }\n ",
1511
+ lang: 'painless'
1512
+ }
1513
+ }
1514
+ }
1515
+ }
1516
+ ];
1517
+
1518
+ filters.forEach((filter) => {
1519
+ it(filter.input.condition, (done) => {
1520
+ const observed = criticalPathAgeFilter(filter.input);
1521
+
1522
+ expect(observed).to.deep.equal(filter.output);
1523
+ done();
1524
+ });
1525
+ });
1526
+ });
@@ -17,7 +17,8 @@ describe('sortScript', function () {
17
17
  type: 'number',
18
18
  script: {
19
19
  lang: 'painless',
20
- source: '\n' +
20
+ source:
21
+ '\n' +
21
22
  " if (!doc['due_date'].empty) {\n" +
22
23
  " return doc['due_date'].value.millis;\n" +
23
24
  ' } else {\n' +
@@ -31,4 +32,17 @@ describe('sortScript', function () {
31
32
  });
32
33
  }
33
34
  });
35
+ describe('criticalPathAge', function () {
36
+ const orders = ['desc', 'asc'];
37
+ for (const order of orders) {
38
+ it(`should handle \`${order}\` sort order`, () => {
39
+ const sort = sortScript.criticalPathAge(order);
40
+ expect(sort).to.be.deep.equal({
41
+ 'critical_path.date_added': {
42
+ order
43
+ }
44
+ });
45
+ });
46
+ }
47
+ });
34
48
  });