@manyos/smileconnect-api 1.28.0
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/.github/workflows/nodejs.yml +26 -0
- package/CHANGELOG.md +75 -0
- package/Dockerfile +21 -0
- package/README.md +1 -0
- package/app.js +316 -0
- package/conf/clients.json +2491 -0
- package/conf/mapping.json +1048 -0
- package/conf/scripts/p1.js +11 -0
- package/conf/scripts/p2.js +1 -0
- package/conf/scripts/p3.js +1 -0
- package/conf/scripts/p4.js +2 -0
- package/conf/scripts/script1.js +2 -0
- package/conf/scripts/script2.js +2 -0
- package/conf/scripts/script3.js +2 -0
- package/controller/cmdbobjectController.js +291 -0
- package/controller/eventLogController.js +78 -0
- package/controller/orgdataController.js +440 -0
- package/controller/relatedObjectsController.js +194 -0
- package/controller/scriptController.js +213 -0
- package/controller/taskController.js +368 -0
- package/controller/templateController.js +97 -0
- package/controller/ticketCIRelationController.js +522 -0
- package/controller/ticketController.js +329 -0
- package/controller/ticketWorkLogController.js +195 -0
- package/docs/.gitattributes +48 -0
- package/docs/404.html +13 -0
- package/docs/CNAME +1 -0
- package/docs/Gemfile +7 -0
- package/docs/Gemfile.lock +249 -0
- package/docs/_config.yml +257 -0
- package/docs/_data/SocialNetworks.yml +92 -0
- package/docs/_data/ui-text.yml +494 -0
- package/docs/_includes/disqus.html +17 -0
- package/docs/_includes/ext-css.html +7 -0
- package/docs/_includes/ext-js.html +7 -0
- package/docs/_includes/fb-comment.html +14 -0
- package/docs/_includes/footer-minimal.html +16 -0
- package/docs/_includes/footer-scripts.html +32 -0
- package/docs/_includes/footer.html +51 -0
- package/docs/_includes/google_analytics.html +14 -0
- package/docs/_includes/gtag.html +11 -0
- package/docs/_includes/gtm_body.html +6 -0
- package/docs/_includes/gtm_head.html +9 -0
- package/docs/_includes/head.html +131 -0
- package/docs/_includes/header.html +76 -0
- package/docs/_includes/just_comments.html +4 -0
- package/docs/_includes/matomo.html +17 -0
- package/docs/_includes/nav.html +57 -0
- package/docs/_includes/social-share.html +42 -0
- package/docs/_includes/staticman-comment.html +22 -0
- package/docs/_includes/staticman-comments.html +81 -0
- package/docs/_layouts/base.html +35 -0
- package/docs/_layouts/default.html +9 -0
- package/docs/_layouts/minimal.html +26 -0
- package/docs/_layouts/page.html +26 -0
- package/docs/_layouts/post.html +82 -0
- package/docs/_posts/2015-02-28-test-markdown.md +77 -0
- package/docs/aboutme.md +18 -0
- package/docs/css/bootstrap-social.css +147 -0
- package/docs/css/bootstrap-theme.css +476 -0
- package/docs/css/bootstrap-theme.css.map +1 -0
- package/docs/css/bootstrap-theme.min.css +5 -0
- package/docs/css/bootstrap.css +6566 -0
- package/docs/css/bootstrap.css.map +1 -0
- package/docs/css/bootstrap.min.css +5 -0
- package/docs/css/main-minimal.css +13 -0
- package/docs/css/main.css +788 -0
- package/docs/css/normalize.css +427 -0
- package/docs/css/pygment_highlights.css +61 -0
- package/docs/css/staticman.css +180 -0
- package/docs/eventlog/events.md +65 -0
- package/docs/feed.xml +24 -0
- package/docs/general/architecture.md +10 -0
- package/docs/general/config.md +192 -0
- package/docs/general/field-management.md +119 -0
- package/docs/general/release-notes.md +9 -0
- package/docs/getting-started.md +19 -0
- package/docs/howto/cmdbobjects.md +339 -0
- package/docs/howto/incident-worklogs.md +186 -0
- package/docs/howto/incidents.md +244 -0
- package/docs/howto/sample-config.md +518 -0
- package/docs/howto/token.md +71 -0
- package/docs/howto/worklog-attachment.md +113 -0
- package/docs/img/404-southpark.jpg +0 -0
- package/docs/img/architecture.jpeg +0 -0
- package/docs/img/attachment-upload.png +0 -0
- package/docs/img/avatar-icon.png +0 -0
- package/docs/img/bgimage.png +0 -0
- package/docs/img/gb-isapi.jpg +0 -0
- package/docs/img/install-steps.gif +0 -0
- package/docs/img/workflow.png +0 -0
- package/docs/index.md +41 -0
- package/docs/installation.md +123 -0
- package/docs/js/bootstrap.js +2306 -0
- package/docs/js/bootstrap.min.js +7 -0
- package/docs/js/jquery-1.11.2.min.js +4 -0
- package/docs/js/main.js +140 -0
- package/docs/js/staticman.js +54 -0
- package/docs/openapi.json +15097 -0
- package/docs/postinstall.md +169 -0
- package/docs/preinstall.md +19 -0
- package/docs/spec/index.html +24 -0
- package/docs/staticman.yml +110 -0
- package/docs/tags.html +34 -0
- package/docs/workflow.md +127 -0
- package/nodemon.json +3 -0
- package/package.json +46 -0
- package/routes/appConfigRoutes.js +352 -0
- package/routes/ciRelationRoutes.js +38 -0
- package/routes/cmdbObjectRoutes.js +154 -0
- package/routes/organisationRoutes.js +121 -0
- package/routes/peopleRelationRoutes.js +38 -0
- package/routes/personRoutes.js +131 -0
- package/routes/supportgroupRoutes.js +122 -0
- package/routes/taskRoutes.js +306 -0
- package/routes/templateRoutes.js +67 -0
- package/routes/ticketRoutes.js +181 -0
- package/routes/ticketWorkLogRoutes.js +185 -0
- package/screwdriver.yaml +52 -0
- package/test/appTest.js +3 -0
- package/test/changeTest.js +541 -0
- package/test/cmdbobjectTest.js +167 -0
- package/test/files/logo.png +0 -0
- package/test/incidentTest.js +539 -0
- package/test/orgdataTest.js +156 -0
- package/test/problemTest.js +512 -0
- package/test/templateTest.js +80 -0
- package/test/testUtils.js +21 -0
- package/test/workorderTest.js +544 -0
- package/util/arquery.js +416 -0
- package/util/auth.js +37 -0
- package/util/cache.service.js +52 -0
- package/util/config.js +361 -0
- package/util/constants.js +73 -0
- package/util/mappingUtil.js +96 -0
- package/util/paramHelper.js +43 -0
- package/util/relationUtil.js +63 -0
- package/util/responsehandler.js +92 -0
- package/util/schemas/clientConfigSchema.js +180 -0
- package/util/schemas/fieldMappingSchema.js +211 -0
- package/util/searchUtil.js +148 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const log = require('@manyos/logger').setupLog('SMILEcatalog_' + path.basename(__filename));
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
|
|
6
|
+
const basePath = 'conf';
|
|
7
|
+
const basePathGlobalScripts = basePath + '/scripts';
|
|
8
|
+
|
|
9
|
+
require('dotenv').config();
|
|
10
|
+
const {NodeVM} = require('vm2');
|
|
11
|
+
|
|
12
|
+
//const adapter = require('../util/adapter').getAdapter();
|
|
13
|
+
|
|
14
|
+
function recFindByExt(base,ext,files,result) {
|
|
15
|
+
const isRoot = (files == undefined);
|
|
16
|
+
files = files || fs.readdirSync(base)
|
|
17
|
+
result = result || []
|
|
18
|
+
|
|
19
|
+
files.forEach(
|
|
20
|
+
function (file) {
|
|
21
|
+
const newbase = path.join(base,file)
|
|
22
|
+
|
|
23
|
+
if ( fs.statSync(newbase).isDirectory() ) {
|
|
24
|
+
result = recFindByExt(newbase,ext,fs.readdirSync(newbase),result)
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
if ( file.substr(-1*(ext.length+1)) == '.' + ext ) {
|
|
28
|
+
result.push(newbase)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
//only in root
|
|
34
|
+
if (isRoot) {
|
|
35
|
+
result = result.map(item => item.replace(base, ''));
|
|
36
|
+
}
|
|
37
|
+
return result
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function executeScriptInternal(scriptId, requestData, params, executedByScript) {
|
|
41
|
+
|
|
42
|
+
const code = await getGlobalScript(scriptId);
|
|
43
|
+
|
|
44
|
+
if (code == undefined || !code) {
|
|
45
|
+
throw (`Script ${scriptId} does not exist!`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return executeCode(code, requestData, params, null, executedByScript);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function executeScript(scriptId, requestData, params) {
|
|
52
|
+
return executeScriptInternal(scriptId, requestData, params, false)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function executeCode(code, requestData, params, logStream, executedByScript) {
|
|
56
|
+
//todo should only be added once
|
|
57
|
+
/*if (logStream) {
|
|
58
|
+
log.addStream(logStream);
|
|
59
|
+
}*/
|
|
60
|
+
|
|
61
|
+
//try to set user data for sandbox
|
|
62
|
+
|
|
63
|
+
async function executeScriptByScript(scriptId, requestData, params) {
|
|
64
|
+
return executeScriptInternal(scriptId, requestData, params, true)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const sandbox = {
|
|
68
|
+
requestData,
|
|
69
|
+
params,
|
|
70
|
+
log,
|
|
71
|
+
script:executeScriptByScript,
|
|
72
|
+
env: {}//process.env
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
sandbox.executedByScript = executedByScript === true;
|
|
76
|
+
|
|
77
|
+
const vm = new NodeVM({
|
|
78
|
+
require: {
|
|
79
|
+
external: true
|
|
80
|
+
},
|
|
81
|
+
sandbox: sandbox,
|
|
82
|
+
wrapper: "none"
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
log.debug('Create vm with sandbox', sandbox);
|
|
86
|
+
|
|
87
|
+
log.debug('run Script', code);
|
|
88
|
+
|
|
89
|
+
//todo Add timeout
|
|
90
|
+
try {
|
|
91
|
+
const result = await vm.run(
|
|
92
|
+
`return new Promise(async function(resolve, reject) {try {${code}} catch (error) {reject(error);}});`,
|
|
93
|
+
'vm.js');
|
|
94
|
+
log.debug('script ended', result);
|
|
95
|
+
return result;
|
|
96
|
+
} catch (e) {
|
|
97
|
+
throw e;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function getGlobalScript(scriptId) {
|
|
102
|
+
const fileName = basePathGlobalScripts + `/${scriptId}.js`;
|
|
103
|
+
return readScriptFromFile(fileName);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function setGlobalScript(scriptId, code) {
|
|
107
|
+
return setScript(basePathGlobalScripts, scriptId, code);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function setScript(dir, scriptId, code) {
|
|
111
|
+
//create folder first
|
|
112
|
+
log.debug('Create dir', dir);
|
|
113
|
+
if (!fs.existsSync(dir)){
|
|
114
|
+
fs.mkdirSync(dir);
|
|
115
|
+
}
|
|
116
|
+
//create subfolders
|
|
117
|
+
const scriptIdSplit = scriptId.split('/');
|
|
118
|
+
if (scriptIdSplit && scriptIdSplit.length > 1) {
|
|
119
|
+
let subDirName = dir;
|
|
120
|
+
for (x=0; x<scriptIdSplit.length -1; x++) {
|
|
121
|
+
subDirName = subDirName + '/' + scriptIdSplit[x];
|
|
122
|
+
if (!fs.existsSync(subDirName)){
|
|
123
|
+
fs.mkdirSync(subDirName);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//create file
|
|
129
|
+
const fileName = `${dir}/${scriptId}.js`;
|
|
130
|
+
log.debug('Write file', fileName);
|
|
131
|
+
return new Promise((res, rej) => {
|
|
132
|
+
fs.writeFile(fileName, code, (err) => {
|
|
133
|
+
if (err) {
|
|
134
|
+
rej(err);
|
|
135
|
+
}
|
|
136
|
+
log.debug(`script written: ${fileName}`);
|
|
137
|
+
res(true);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function deleteScript(dir, scriptId) {
|
|
143
|
+
return new Promise((res, rej) => {
|
|
144
|
+
fs.unlink(`${dir}/${scriptId}.js`, (err) => {
|
|
145
|
+
if (err) {
|
|
146
|
+
rej(err);
|
|
147
|
+
}
|
|
148
|
+
log.debug(`script removed: ${dir}/${scriptId}`);
|
|
149
|
+
res({
|
|
150
|
+
id: scriptId,
|
|
151
|
+
status: "deleted"
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async function deleteGlobalScript(scriptId) {
|
|
158
|
+
return deleteScript(basePathGlobalScripts, scriptId);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function readScriptFromFile(fileName) {
|
|
162
|
+
log.debug('Read file', fileName);
|
|
163
|
+
const script = fs.readFileSync(fileName,{encoding: 'utf8'});
|
|
164
|
+
log.debug('found script', script);
|
|
165
|
+
return script;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function getScripts(pathName, catalogType, catalogId) {
|
|
169
|
+
const files = recFindByExt(pathName,'js')
|
|
170
|
+
const scriptNames = files.map(file => file.substr(0, file.length-3));
|
|
171
|
+
log.debug(scriptNames);
|
|
172
|
+
const scripts = [];
|
|
173
|
+
for (let x=0; x<scriptNames.length; x++) {
|
|
174
|
+
if (!catalogType) {
|
|
175
|
+
const script = {
|
|
176
|
+
id: scriptNames[x],
|
|
177
|
+
code: await getGlobalScript(scriptNames[x])
|
|
178
|
+
};
|
|
179
|
+
scripts.push(script);
|
|
180
|
+
} else {
|
|
181
|
+
const script = {
|
|
182
|
+
id: scriptNames[x],
|
|
183
|
+
code: await getCatalogScript(catalogType, catalogId, scriptNames[x])
|
|
184
|
+
};
|
|
185
|
+
scripts.push(script);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return scripts;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function getGlobalScripts() {
|
|
192
|
+
const path = `${basePathGlobalScripts}/`;
|
|
193
|
+
return getScripts(path);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function runScripts(scripts, data) {
|
|
197
|
+
try {
|
|
198
|
+
for (let x = 0; x < scripts.length; x++) {
|
|
199
|
+
await executeScript(scripts[x], data);
|
|
200
|
+
}
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
module.exports = {
|
|
207
|
+
executeScript,
|
|
208
|
+
getGlobalScript,
|
|
209
|
+
getGlobalScripts,
|
|
210
|
+
setGlobalScript,
|
|
211
|
+
deleteGlobalScript,
|
|
212
|
+
runScripts
|
|
213
|
+
};
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
require('dotenv').config();
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
|
|
4
|
+
const arquery = require('../util/arquery');
|
|
5
|
+
const CacheService = require ('../util/cache.service');
|
|
6
|
+
const config = require('../util/config');
|
|
7
|
+
const CONSTANTS = require('../util/constants');
|
|
8
|
+
const relationUtil = require('../util/relationUtil');
|
|
9
|
+
const mappingUtil = require('../util/mappingUtil');
|
|
10
|
+
const scriptController = require('./scriptController');
|
|
11
|
+
|
|
12
|
+
const taskCache = new CacheService(process.env.CACHETTL_TASK || 0); // Create a new cache service instance
|
|
13
|
+
|
|
14
|
+
function getTasks(config, category) {
|
|
15
|
+
let query = '1=1';
|
|
16
|
+
if (category)
|
|
17
|
+
query = `'Category' = \"${category}\"`;
|
|
18
|
+
return queryTasks(config, query);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getTasksByRootRequest(config, rootRequestId, rootRequestForm) {
|
|
22
|
+
const query = `'RootRequestID' = \"${rootRequestId}\" AND 'RootRequestFormName' = \"${rootRequestForm}\"`;
|
|
23
|
+
return queryTasks(config, query);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function createTask(clientConfig, rootForm, rootRequestId, taskData, createTaskFlow) {
|
|
27
|
+
const scripts = clientConfig.task.scripts.POST;
|
|
28
|
+
const fields = clientConfig.task.fields;
|
|
29
|
+
|
|
30
|
+
log.debug('data', taskData);
|
|
31
|
+
let subQuery = "'1' = \"rootRequestId\"";
|
|
32
|
+
if (rootForm === CONSTANTS.FORM_WORKORDER) {
|
|
33
|
+
subQuery = `'Work Order ID'=\"${rootRequestId}\"`;
|
|
34
|
+
} else if (rootForm === CONSTANTS.FORM_INCIDENT) {
|
|
35
|
+
subQuery = `'Incident Number'=\"${rootRequestId}\"`;
|
|
36
|
+
} else if (rootForm === CONSTANTS.FORM_PROBLEM) {
|
|
37
|
+
subQuery = `'Problem Investigation ID'=\"${rootRequestId}\"`;
|
|
38
|
+
} else if (rootForm === CONSTANTS.FORM_CHANGE) {
|
|
39
|
+
subQuery = `'Infrastructure Change ID'=\"${rootRequestId}\"`;
|
|
40
|
+
}
|
|
41
|
+
//Read instanceId from Root request
|
|
42
|
+
|
|
43
|
+
const rootRequest = await arquery.executeARQuery(rootForm, null, subQuery, "InstanceId", clientConfig.options)
|
|
44
|
+
log.debug('found RootRequest', rootRequest);
|
|
45
|
+
if (rootRequest.data && Array.isArray(rootRequest.data)) {
|
|
46
|
+
let allTask = [];
|
|
47
|
+
if (Array.isArray(taskData)) {
|
|
48
|
+
allTask = taskData;
|
|
49
|
+
} else {
|
|
50
|
+
allTask.push(taskData);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const mapping = config.getMapping('newTask');
|
|
54
|
+
//add required data
|
|
55
|
+
|
|
56
|
+
const allTaskFinal = [];
|
|
57
|
+
allTask.forEach(thisTask => {
|
|
58
|
+
thisTask.TaskName = thisTask.summary;
|
|
59
|
+
thisTask.TaskType = 2000;
|
|
60
|
+
thisTask.Status = 1000;
|
|
61
|
+
thisTask.RootRequestFormName = rootForm;
|
|
62
|
+
thisTask.RootRequestMode = "1";
|
|
63
|
+
thisTask.RootRequestName = rootRequestId;
|
|
64
|
+
thisTask.RootRequestInstanceId = rootRequest.data[0]['InstanceId'];
|
|
65
|
+
thisTask.sequence = thisTask.sequence || "1";
|
|
66
|
+
allTaskFinal.push(thisTask);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
fields.push('TaskName', 'RootRequestInstanceId', 'TaskType', 'Status', 'RootRequestFormName', 'RootRequestMode', 'RootRequestName', 'sequence')
|
|
70
|
+
|
|
71
|
+
//run preScripts
|
|
72
|
+
if (scripts && scripts.preMapping) {
|
|
73
|
+
await scriptController.runScripts(scripts.preMapping, taskData);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
taskData = mappingUtil.applyMapping2Remedy(taskData, mapping, clientConfig.task.constants, fields);
|
|
77
|
+
|
|
78
|
+
//run postScripts
|
|
79
|
+
if (scripts && scripts.postMapping) {
|
|
80
|
+
await scriptController.runScripts(scripts.postMapping, taskData);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const taskResult = await arquery.createEntry('TMS:Task', taskData, clientConfig.options)
|
|
84
|
+
|
|
85
|
+
//run afterExecution
|
|
86
|
+
if (scripts && scripts.afterExecution) {
|
|
87
|
+
await scriptController.runScripts(scripts.afterExecution, data);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
log.debug('Create Task Result', taskResult);
|
|
91
|
+
let flowBuilderRequest = {
|
|
92
|
+
"RootRequestFormName" : rootForm,
|
|
93
|
+
"RootRequestName" : rootRequestId,
|
|
94
|
+
"RootRequestInstanceId" : rootRequest.data[0]['InstanceId'],
|
|
95
|
+
"zTmpInternalCommand" : "CREATE",
|
|
96
|
+
"Parent Type" : "0",
|
|
97
|
+
"ParentID" : rootRequest.data[0]['InstanceId'],
|
|
98
|
+
"Parent Name" : rootRequestId
|
|
99
|
+
};
|
|
100
|
+
log.debug('createFlow', createTaskFlow === true);
|
|
101
|
+
if (createTaskFlow != null && createTaskFlow === true ) {
|
|
102
|
+
const mappingflow = config.getMapping('flowBuilder');
|
|
103
|
+
|
|
104
|
+
flowBuilderRequest = mappingUtil.applyMapping2Remedy(flowBuilderRequest, mappingflow, clientConfig.flowBuilder.constants);
|
|
105
|
+
|
|
106
|
+
const taskFlowResult = await arquery.createEntry('TMS:FlowBuilder', flowBuilderRequest, clientConfig.options)
|
|
107
|
+
log.debug('TaskFlowBuilder Result', taskFlowResult);
|
|
108
|
+
return taskResult;
|
|
109
|
+
} else {
|
|
110
|
+
log.debug('Task flow update not requested');
|
|
111
|
+
return taskResult;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function createWorklog(clientConfig, taskId, summary, text, attachment) {
|
|
117
|
+
const task = await getTask(clientConfig,taskId)
|
|
118
|
+
const fields = clientConfig.taskWorklog.fields;
|
|
119
|
+
|
|
120
|
+
const taskInstanceId = task.instanceId;
|
|
121
|
+
|
|
122
|
+
const scripts = clientConfig.taskWorklog.scripts.POST;
|
|
123
|
+
|
|
124
|
+
const mapping = config.getMapping('taskWorklog');
|
|
125
|
+
|
|
126
|
+
log.debug('mapping', mapping);
|
|
127
|
+
let data = {
|
|
128
|
+
"Secure Log" : "Yes",
|
|
129
|
+
"summary" : summary,
|
|
130
|
+
"text" : text,
|
|
131
|
+
"TaskOrTaskGroupID" : taskId,
|
|
132
|
+
"TaskOrTaskGroupInstanceId" : taskInstanceId
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
fields.push(
|
|
136
|
+
'Secure Log',
|
|
137
|
+
'TaskOrTaskGroupID',
|
|
138
|
+
'TaskOrTaskGroupInstanceId'
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
//run preScripts
|
|
142
|
+
if (scripts && scripts.preMapping) {
|
|
143
|
+
await scriptController.runScripts(scripts.preMapping, data);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
data = mappingUtil.applyMapping2Remedy(data, mapping, clientConfig.taskWorklog.constants, fields);
|
|
147
|
+
|
|
148
|
+
//run postScripts
|
|
149
|
+
if (scripts && scripts.postMapping) {
|
|
150
|
+
await scriptController.runScripts(scripts.postMapping, data);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const result = await arquery.createEntry('TMS:WorkInfo', data, clientConfig.options)
|
|
154
|
+
|
|
155
|
+
//run afterExecution
|
|
156
|
+
if (scripts && scripts.afterExecution) {
|
|
157
|
+
await scriptController.runScripts(scripts.afterExecution, data);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return(result);
|
|
161
|
+
//todo add attachment handling
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function queryTasks(clientConfig, query) {
|
|
165
|
+
const scripts = clientConfig.task.scripts.GET;
|
|
166
|
+
|
|
167
|
+
const key = clientConfig.task.basequery + clientConfig.task.fields.toString() + query;
|
|
168
|
+
log.debug('Cachekey is', key);
|
|
169
|
+
|
|
170
|
+
const mapping = config.getMapping('task');
|
|
171
|
+
log.debug('mapping', mapping);
|
|
172
|
+
|
|
173
|
+
return taskCache.get(key, async function () {
|
|
174
|
+
const result = await arquery.executeARQuery('TMS:Task', clientConfig.task.basequery || null, query, clientConfig.task.fields.toString() || '1', clientConfig.options)
|
|
175
|
+
const globalRelationObjects = relationUtil.prepareGlobalRelationObject();
|
|
176
|
+
if (result.data && Array.isArray(result.data)) {
|
|
177
|
+
let x;
|
|
178
|
+
for (x=0; x< result.data.length; x++) {
|
|
179
|
+
const element = result.data[x];
|
|
180
|
+
//check for included objects
|
|
181
|
+
const customerId = element['Customer Person ID'];
|
|
182
|
+
if (customerId != null && customerId !== undefined)
|
|
183
|
+
globalRelationObjects.persons.add(customerId);
|
|
184
|
+
|
|
185
|
+
const supportGroupId = element['Support Group ID'];
|
|
186
|
+
if (supportGroupId != null && supportGroupId !== undefined)
|
|
187
|
+
globalRelationObjects.supportgroups.add(supportGroupId);
|
|
188
|
+
|
|
189
|
+
const supportGroupId2 = element['Support Group ID 2'];
|
|
190
|
+
if (supportGroupId2 != null && supportGroupId2 !== undefined)
|
|
191
|
+
globalRelationObjects.supportgroups.add(supportGroupId2);
|
|
192
|
+
|
|
193
|
+
const requestorId = element['Requested By Person ID'];
|
|
194
|
+
if (requestorId != null && requestorId !== undefined)
|
|
195
|
+
globalRelationObjects.supportgroups.add(requestorId);
|
|
196
|
+
|
|
197
|
+
//run preScripts
|
|
198
|
+
if (scripts && scripts.preMapping) {
|
|
199
|
+
await scriptController.runScripts(scripts.preMapping, element);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
//Apply mapping
|
|
203
|
+
mapping.forEach(function (mappingEntry) {
|
|
204
|
+
try {
|
|
205
|
+
Object.defineProperty(element, mappingEntry.newName, Object.getOwnPropertyDescriptor(element, mappingEntry.oldName));
|
|
206
|
+
delete element[mappingEntry.oldName];
|
|
207
|
+
} catch (e) {
|
|
208
|
+
//ignore missing mapping
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
delete element['Request ID'];
|
|
212
|
+
|
|
213
|
+
//run preScripts
|
|
214
|
+
if (scripts && scripts.postMapping) {
|
|
215
|
+
await scriptController.runScripts(scripts.postMapping, element);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return ({
|
|
219
|
+
"data": result.data,
|
|
220
|
+
"included": {
|
|
221
|
+
"persons": Array.from(globalRelationObjects.persons),
|
|
222
|
+
"organisations": Array.from(globalRelationObjects.organisations),
|
|
223
|
+
"supportgroups": Array.from(globalRelationObjects.supportgroups)
|
|
224
|
+
}});
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return ({"data":[]});
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async function queryWorklogs(clientConfig, query, mapping) {
|
|
233
|
+
|
|
234
|
+
const scripts = clientConfig.taskWorklog.scripts.GET;
|
|
235
|
+
|
|
236
|
+
const fields = clientConfig.taskWorklog.fields;
|
|
237
|
+
const basequery = clientConfig.taskWorklog.basequery;
|
|
238
|
+
const key = 'worklog' + basequery + fields.toString() + query;
|
|
239
|
+
log.debug('Cachekey is ', key);
|
|
240
|
+
if (mapping == null || mapping == undefined) {
|
|
241
|
+
mapping = config.getMapping('taskWorklog');
|
|
242
|
+
}
|
|
243
|
+
log.debug('mapping', mapping);
|
|
244
|
+
log.debug('fields', fields);
|
|
245
|
+
|
|
246
|
+
return taskCache.get(key, async function () {
|
|
247
|
+
const result = await arquery.executeARQuery(CONSTANTS.FORM_TASK_WORKLOG, basequery || null, query, fields.toString() || '1', clientConfig.options)
|
|
248
|
+
if (result.data && Array.isArray(result.data)) {
|
|
249
|
+
let x;
|
|
250
|
+
for (x=0; x< result.data.length; x++) {
|
|
251
|
+
const element = result.data[x];
|
|
252
|
+
|
|
253
|
+
//run preScripts
|
|
254
|
+
if (scripts && scripts.preMapping) {
|
|
255
|
+
await scriptController.runScripts(scripts.preMapping, element);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
//Apply mapping
|
|
259
|
+
mapping.forEach(function (mappingEntry) {
|
|
260
|
+
try {
|
|
261
|
+
Object.defineProperty(element, mappingEntry.newName, Object.getOwnPropertyDescriptor(element, mappingEntry.oldName));
|
|
262
|
+
delete element[mappingEntry.oldName];
|
|
263
|
+
} catch (e) {
|
|
264
|
+
//ignore missing mapping
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
//delete element['Entry ID'];
|
|
268
|
+
|
|
269
|
+
//run postScripts
|
|
270
|
+
if (scripts && scripts.postMapping) {
|
|
271
|
+
await scriptController.runScripts(scripts.postMapping, element);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
"data": result.data
|
|
276
|
+
};
|
|
277
|
+
} else {
|
|
278
|
+
return {"data":[]};
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async function getTask(clientConfig, id) {
|
|
284
|
+
const query = `'Task ID'=\"${id}\"`;
|
|
285
|
+
const tasks = await queryTasks(clientConfig, query);
|
|
286
|
+
return tasks.data[0];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async function getTaskByRootRequest(config, rootRequestId, taskId) {
|
|
290
|
+
const query = `'Task ID'=\"${taskId}\" AND 'RootRequestID' = \"${rootRequestId}\"`;
|
|
291
|
+
const returnValue = await queryTasks(config, query);
|
|
292
|
+
const task = returnValue.data[0];
|
|
293
|
+
return {data: task, included: returnValue.included};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function getTaskWorklogs(config, taskId) {
|
|
297
|
+
const query = `'TaskOrTaskGroupID'=\"${taskId}\"`;
|
|
298
|
+
return queryWorklogs(config, query);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async function getTaskWorklog(config, taskId, worklogId) {
|
|
302
|
+
const query = `'TaskOrTaskGroupID'=\"${taskId}\" AND 'Work Info ID'=\"${worklogId}\"`;
|
|
303
|
+
const returnValue = await queryWorklogs(config, query);
|
|
304
|
+
log.debug ('rtn', returnValue);
|
|
305
|
+
const worklog = returnValue.data[0];
|
|
306
|
+
return {data: worklog, included: returnValue.included};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async function updateTask(clientConfig, id, taskData) {
|
|
310
|
+
const mapping = config.getMapping('task');
|
|
311
|
+
const taskConstants = clientConfig.task.constants;
|
|
312
|
+
const scripts = clientConfig.task.scripts.PUT;
|
|
313
|
+
const fields = clientConfig.task.fields;
|
|
314
|
+
|
|
315
|
+
//run preScripts
|
|
316
|
+
if (scripts && scripts.preMapping) {
|
|
317
|
+
await scriptController.runScripts(scripts.preMapping, taskData);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
taskData = mappingUtil.applyMapping2Remedy(taskData, mapping, taskConstants, fields);
|
|
321
|
+
|
|
322
|
+
//run postScripts
|
|
323
|
+
if (scripts && scripts.postMapping) {
|
|
324
|
+
await scriptController.runScripts(scripts.postMapping, taskData);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const result = await arquery.updateEntry('TMS:Task', id, taskData);
|
|
328
|
+
|
|
329
|
+
//run afterExecution
|
|
330
|
+
if (scripts && scripts.afterExecution) {
|
|
331
|
+
await scriptController.runScripts(scripts.afterExecution, taskData);
|
|
332
|
+
}
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function setWorklogAttachment(clientConfig, worklogId, file, attachmentId) {
|
|
337
|
+
const fieldId = getAttachmentFieldId(attachmentId);
|
|
338
|
+
return arquery.setAttachment(CONSTANTS.FORM_TASK_WORKLOG, worklogId, fieldId, file);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function getWorklogAttachment(clientConfig, worklogId, attachmentId) {
|
|
342
|
+
const fieldId = getAttachmentFieldId(attachmentId);
|
|
343
|
+
return arquery.getAttachment(CONSTANTS.FORM_TASK_WORKLOG, worklogId, fieldId);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function getAttachmentFieldId(attachmentId) {
|
|
347
|
+
let attachmentFieldId = 10001831;
|
|
348
|
+
if (attachmentId == 2) {
|
|
349
|
+
attachmentFieldId = 10001832;
|
|
350
|
+
} else if (attachmentId == 3) {
|
|
351
|
+
attachmentFieldId = 10001833;
|
|
352
|
+
}
|
|
353
|
+
log.debug('AttachmentFieldId', attachmentFieldId);
|
|
354
|
+
return attachmentFieldId;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
module.exports = {
|
|
358
|
+
getTaskByRootRequest,
|
|
359
|
+
getTasks,
|
|
360
|
+
getTaskWorklogs,
|
|
361
|
+
getTaskWorklog,
|
|
362
|
+
updateTask,
|
|
363
|
+
createTask,
|
|
364
|
+
getTasksByRootRequest,
|
|
365
|
+
createWorklog,
|
|
366
|
+
setWorklogAttachment,
|
|
367
|
+
getWorklogAttachment
|
|
368
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require('dotenv').config();
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
|
|
4
|
+
const arquery = require('../util/arquery');
|
|
5
|
+
const CacheService = require ('../util/cache.service');
|
|
6
|
+
const config = require('../util/config');
|
|
7
|
+
const {getIncludeArray, applyMapping} = require('../util/paramHelper');
|
|
8
|
+
const relationUtil = require('../util/relationUtil');
|
|
9
|
+
|
|
10
|
+
const templateCache = new CacheService(process.env.CACHETTL_TEMPLATE || 1); // Create a new cache service instance
|
|
11
|
+
|
|
12
|
+
function getTemplates(ticketConfig, config, includeString, customOptions) {
|
|
13
|
+
let query = '1=1';
|
|
14
|
+
return queryTemplates(ticketConfig, config, query, null, null, customOptions, includeString);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function queryTemplates(ticketConfig, clientConfig, query, mapping, customFields, customOptions, includeString) {
|
|
18
|
+
log.debug('config', ticketConfig);
|
|
19
|
+
const includeArray = getIncludeArray(includeString);
|
|
20
|
+
log.debug('ticketConfig.requestType', ticketConfig.requestType);
|
|
21
|
+
let fields = clientConfig[ticketConfig.requestTemplate].fields;
|
|
22
|
+
|
|
23
|
+
log.debug('fieldi', fields);
|
|
24
|
+
log.debug('else', ticketConfig.requestTemplate);
|
|
25
|
+
const baseQuery = clientConfig[ticketConfig.requestTemplate].basequery;
|
|
26
|
+
|
|
27
|
+
//check for customFields
|
|
28
|
+
if (customFields !== null && customFields !== undefined) {
|
|
29
|
+
fields = customFields;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
log.debug('fields', fields, customFields);
|
|
33
|
+
const options = {
|
|
34
|
+
...clientConfig.options, ...customOptions
|
|
35
|
+
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
log.debug('use joined options', options);
|
|
39
|
+
|
|
40
|
+
const key = baseQuery + fields.toString() + query + JSON.stringify(options) + includeArray;
|
|
41
|
+
log.debug('Cachekey is ', key);
|
|
42
|
+
if (mapping == null || mapping == undefined) {
|
|
43
|
+
mapping = config.getMapping(ticketConfig.requestTemplate);
|
|
44
|
+
}
|
|
45
|
+
log.debug('mapping', mapping);
|
|
46
|
+
|
|
47
|
+
return templateCache.get(key, async function () {
|
|
48
|
+
const result = await arquery.executeARQuery(ticketConfig.forms.template, baseQuery || null, query, fields.toString() || '1', options);
|
|
49
|
+
const globalRelationObjects = relationUtil.prepareGlobalRelationObject();
|
|
50
|
+
const tickets = [];
|
|
51
|
+
if (result && result.data && result.data.length) {
|
|
52
|
+
let x = 0;
|
|
53
|
+
for (x=0; x< result.data.length; x++) {
|
|
54
|
+
//const ticket = await handleTemplate(ticketConfig, result.data[x], mapping, clientConfig, includeArray, globalRelationObjects);
|
|
55
|
+
const ticket = result.data[x];
|
|
56
|
+
applyMapping(ticket, mapping, ticketConfig.templateRequestId);
|
|
57
|
+
tickets.push(ticket);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
log.debug('tickets', tickets);
|
|
61
|
+
return {
|
|
62
|
+
"data": tickets,
|
|
63
|
+
"included": globalRelationObjects
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function getTemplate(ticketConfig, config, id, mapping, includeString) {
|
|
69
|
+
let query = `'179'="${id}"`;
|
|
70
|
+
/*const requestType = ticketConfig.requestType;
|
|
71
|
+
if (requestType === 'incident') {
|
|
72
|
+
query = `'HPD Template ID'=\"${id}\"`;
|
|
73
|
+
} else if (requestType === 'change') {
|
|
74
|
+
query = `'Infrastructure Change ID'=\"${id}\"`;
|
|
75
|
+
} else if (requestType === 'problem') {
|
|
76
|
+
query = `'Problem Investigation ID'=\"${id}\"`;
|
|
77
|
+
} else if (requestType === 'workOrder') {
|
|
78
|
+
query = `'Work Order ID'=\"${id}\"`;
|
|
79
|
+
}*/
|
|
80
|
+
const returnValue = await queryTemplates(ticketConfig, config, query, mapping, null, null, includeString);
|
|
81
|
+
const ticket = returnValue.data[0];
|
|
82
|
+
return {data: ticket, included: returnValue.included};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
function searchTicket(ticketConfig, clientConfig, searchString, fields, options, includeString) {
|
|
87
|
+
const mapping = config.getMapping(ticketConfig.requestType);
|
|
88
|
+
const mappedString = searchUtil.applyMapping(searchString, mapping);
|
|
89
|
+
const customFields = searchUtil.getCustomFields(clientConfig[ticketConfig.requestType].fields, mapping, fields);
|
|
90
|
+
options.sort = searchUtil.applySortMapping(options.sort, mapping);
|
|
91
|
+
return queryTickets(ticketConfig, clientConfig, mappedString, null, customFields, options, includeString);
|
|
92
|
+
}*/
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
getTemplate,
|
|
96
|
+
getTemplates
|
|
97
|
+
};
|