@pxp-nd/flow 1.0.76 → 1.0.77

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.
@@ -16,6 +16,7 @@
16
16
  * 18-Aug-2023 SP25AUG23 Mercedes Zambrana Add removeFlow
17
17
  * 01-Sep-2023 SP08SEP23 Rensi Arteaga add base flow list
18
18
  * 16-Sep-2023 SP22SEP23 Mercedes Zambrana Change GET to POST in insertEventFlow
19
+ * 28-Sep-2023 SP06OCT23 Mercedes Zambrana Add Validation when change off status (validateFlow, deleteflow, saveFlow, saveflowName)
19
20
  * ******************************************************************************
20
21
  */
21
22
  import { EntityManager } from 'typeorm';
@@ -36,7 +37,7 @@ declare class Flow extends Controller {
36
37
  insertEventFlow(params: Record<string, any>, manager: EntityManager): Promise<unknown>;
37
38
  removeFlow(params: Record<string, any>, manager: EntityManager): Promise<unknown>;
38
39
  changeStatusFlow(params: Record<string, any>, manager: EntityManager): Promise<unknown>;
39
- validateFlow(flowId: number, manager: EntityManager): Promise<unknown>;
40
+ validateFlow(flowId: number, manager: EntityManager, status: string): Promise<unknown>;
40
41
  basicFlowList(params: Record<string, any>): Promise<unknown>;
41
42
  }
42
43
  export default Flow;
@@ -17,6 +17,7 @@
17
17
  * 18-Aug-2023 SP25AUG23 Mercedes Zambrana Add removeFlow
18
18
  * 01-Sep-2023 SP08SEP23 Rensi Arteaga add base flow list
19
19
  * 16-Sep-2023 SP22SEP23 Mercedes Zambrana Change GET to POST in insertEventFlow
20
+ * 28-Sep-2023 SP06OCT23 Mercedes Zambrana Add Validation when change off status (validateFlow, deleteflow, saveFlow, saveflowName)
20
21
  * ******************************************************************************
21
22
  */
22
23
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
@@ -62,6 +63,9 @@ const Node_1 = __importDefault(require("../entity/Node"));
62
63
  const Action_1 = __importDefault(require("../entity/Action"));
63
64
  const NodeConnection_1 = __importDefault(require("../entity/NodeConnection"));
64
65
  const Flow_1 = __importDefault(require("../entity/Flow"));
66
+ const FlowInstance_1 = __importDefault(require("../entity/FlowInstance"));
67
+ const NodeInstance_1 = __importDefault(require("../entity/NodeInstance"));
68
+ //import {configFacebookStrategy} from "./passport-facebook";
65
69
  let Flow = class Flow extends core_1.Controller {
66
70
  async get(params) {
67
71
  const nodes = await Node_1.default.find({ flowId: params.flowId });
@@ -137,6 +141,9 @@ let Flow = class Flow extends core_1.Controller {
137
141
  async deleteFlow(params, manager) {
138
142
  let dataFlow = await (0, core_1.__)(Flow_1.default.findOne(params.flowId));
139
143
  if (dataFlow) {
144
+ if (dataFlow.status == 'on') {
145
+ throw new core_1.PxpError(400, 'Your flow is on. It is not possible to delete it');
146
+ }
140
147
  dataFlow.isActive = 0;
141
148
  dataFlow.enabled = 'N';
142
149
  dataFlow.modifiedAt = new Date();
@@ -176,6 +183,9 @@ let Flow = class Flow extends core_1.Controller {
176
183
  async saveFlowName(params, manager) {
177
184
  let dataFlow = await (0, core_1.__)(Flow_1.default.findOne(params.flowId));
178
185
  if (dataFlow) {
186
+ if (dataFlow.status == 'on') {
187
+ throw new core_1.PxpError(400, 'Your flow is on. It is not possible to change the name');
188
+ }
179
189
  dataFlow.name = params.name;
180
190
  dataFlow.modifiedAt = new Date();
181
191
  dataFlow.modifiedBy = this.user.username;
@@ -220,6 +230,8 @@ let Flow = class Flow extends core_1.Controller {
220
230
  let id = null;
221
231
  let newId = null;
222
232
  let flowId = null;
233
+ let allowModify = false;
234
+ let dataFlow = null;
223
235
  let taskIds = [];
224
236
  if (nodeRefIds.length === 0) {
225
237
  let nodeDelIdd = parseInt(params.board.deleteId.split("-")[1]);
@@ -229,9 +241,12 @@ let Flow = class Flow extends core_1.Controller {
229
241
  }
230
242
  });
231
243
  flowId = lastNoded.flowId;
244
+ dataFlow = await (0, core_1.__)(Flow_1.default.findOne(flowId));
245
+ if (dataFlow.status == 'off') {
246
+ allowModify = true;
247
+ }
232
248
  }
233
249
  else {
234
- flowId = params.board.flowId;
235
250
  for (const nodeId of nodeRefIds) {
236
251
  if (nodeId != 'new') {
237
252
  id = parseInt(nodeId.split("node-")[1]);
@@ -247,14 +262,26 @@ let Flow = class Flow extends core_1.Controller {
247
262
  id = lastNode.nodeId;
248
263
  }
249
264
  taskIds.push(id);
250
- const connectionsToDel = await manager.find(NodeConnection_1.default, {
251
- where: { nodeIdChild: id }
252
- });
253
- if (connectionsToDel) {
254
- const originalNodeCIds = connectionsToDel.map((node) => node.nodeConnectionId);
255
- let flowNodeC = await (0, typeorm_1.getManager)().query(`DELETE
265
+ if (!flowId) {
266
+ const DataFlowId = await Node_1.default.findOne({
267
+ where: {
268
+ nodeId: id,
269
+ }
270
+ });
271
+ flowId = DataFlowId.flowId;
272
+ }
273
+ dataFlow = await (0, core_1.__)(Flow_1.default.findOne(flowId));
274
+ if (dataFlow.status == 'off') {
275
+ allowModify = true;
276
+ const connectionsToDel = await manager.find(NodeConnection_1.default, {
277
+ where: { nodeIdChild: id }
278
+ });
279
+ if (connectionsToDel) {
280
+ const originalNodeCIds = connectionsToDel.map((node) => node.nodeConnectionId);
281
+ let flowNodeC = await (0, typeorm_1.getManager)().query(`DELETE
256
282
  from twf_node_connection
257
283
  WHERE node_connection_id = ${originalNodeCIds}`);
284
+ }
258
285
  }
259
286
  }
260
287
  else {
@@ -265,58 +292,73 @@ let Flow = class Flow extends core_1.Controller {
265
292
  if (params.board.origin == 'deleteTask') {
266
293
  let nodeDelId = parseInt(params.board.deleteId.split("-")[1]);
267
294
  if (nodeDelId) {
268
- //If there are some nodes in node_connections after delete all records sent, to inactive node
269
- let connectNoDel = await (0, typeorm_1.getManager)().query(`SELECT n.node_id
295
+ const flowIdDel = await Node_1.default.findOne({ nodeId: nodeDelId });
296
+ flowId = flowIdDel.flowId;
297
+ dataFlow = await (0, core_1.__)(Flow_1.default.findOne(flowId));
298
+ if (dataFlow.status == 'off') {
299
+ allowModify = true;
300
+ //If there are some nodes in node_connections after delete all records sent, to inactive node
301
+ let connectNoDel = await (0, typeorm_1.getManager)().query(`SELECT n.node_id
270
302
  from twf_node_connection nd
271
303
  inner join twf_node n on n.node_id = nd.node_id_child
272
304
  WHERE n.node_id = ${nodeDelId}`);
273
- const currentNodesIds = connectNoDel.map((record) => record.node_id);
274
- // Get nodes to remove
275
- const nodesToRemove = currentNodesIds.filter((nodeId) => !taskIds.includes(nodeId.toString()));
276
- // Inactive nodes
277
- if (nodesToRemove.length > 0) {
278
- const delNodeConnect = await manager.delete(NodeConnection_1.default, { nodeIdChild: nodesToRemove[0] });
279
- if (delNodeConnect) {
280
- let dNode = `UPDATE twf_node
305
+ const currentNodesIds = connectNoDel.map((record) => record.node_id);
306
+ // Get nodes to remove
307
+ const nodesToRemove = currentNodesIds.filter((nodeId) => !taskIds.includes(nodeId.toString()));
308
+ // Inactive nodes
309
+ if (nodesToRemove.length > 0) {
310
+ const delNodeConnect = await manager.delete(NodeConnection_1.default, { nodeIdChild: nodesToRemove[0] });
311
+ if (delNodeConnect) {
312
+ let dNode = `UPDATE twf_node
281
313
  SET is_active = 'N'
282
314
  WHERE node_id = ${nodesToRemove[0]}`;
283
- await manager.query(dNode);
315
+ await manager.query(dNode);
316
+ }
284
317
  }
285
318
  }
319
+ else {
320
+ throw new core_1.PxpError(400, 'AAA: Please turn off the flow before make a change');
321
+ }
286
322
  }
287
323
  }
288
324
  if (nodeRefIds.length === 0) {
289
325
  }
290
326
  else {
291
- for (const nodeId of taskIds) {
292
- if (nodeId === 'new') {
293
- //get information about Action
294
- const newAction = await Action_1.default.findOne({ code: nodes[`${nodeId}`].action.code });
295
- const newNode = manager.create(Node_1.default, {
296
- nodeId: undefined,
297
- flowId: nodes[`${nodeId}`].flowId,
298
- isInit: 'N',
299
- actionId: newAction.actionId
327
+ dataFlow = await (0, core_1.__)(Flow_1.default.findOne(flowId));
328
+ if (dataFlow.status == 'off') {
329
+ allowModify = true;
330
+ for (const nodeId of taskIds) {
331
+ if (nodeId === 'new') {
332
+ //get information about Action
333
+ const newAction = await Action_1.default.findOne({ code: nodes[`${nodeId}`].action.code });
334
+ const newNode = manager.create(Node_1.default, {
335
+ nodeId: undefined,
336
+ flowId: nodes[`${nodeId}`].flowId,
337
+ isInit: 'N',
338
+ actionId: newAction.actionId
339
+ });
340
+ const saveNode = await manager.save(newNode);
341
+ id = saveNode.nodeId;
342
+ newId = saveNode.nodeId;
343
+ }
344
+ else {
345
+ id = nodeId;
346
+ }
347
+ //save in node and node_connection
348
+ const newConnection = manager.create(NodeConnection_1.default, {
349
+ nodeConnectionId: undefined,
350
+ nodeIdMaster: masterId,
351
+ nodeIdChild: id,
300
352
  });
301
- const saveNode = await manager.save(newNode);
302
- id = saveNode.nodeId;
303
- newId = saveNode.nodeId;
304
- }
305
- else {
306
- id = nodeId;
353
+ masterId = id;
354
+ const savedNodes = await manager.save(newConnection);
307
355
  }
308
- //save in node and node_connection
309
- const newConnection = manager.create(NodeConnection_1.default, {
310
- nodeConnectionId: undefined,
311
- nodeIdMaster: masterId,
312
- nodeIdChild: id,
313
- });
314
- masterId = id;
315
- const savedNodes = await manager.save(newConnection);
356
+ }
357
+ else {
358
+ throw new core_1.PxpError(400, 'Please turn off the flow before make a change');
316
359
  }
317
360
  }
318
- let dataFlow = await (0, core_1.__)(Flow_1.default.findOne(flowId));
319
- if (dataFlow) {
361
+ if (dataFlow && allowModify) {
320
362
  dataFlow.modifiedAt = new Date();
321
363
  dataFlow.modifiedBy = this.user.username;
322
364
  await (0, core_1.__)(manager.save(dataFlow));
@@ -513,11 +555,12 @@ let Flow = class Flow extends core_1.Controller {
513
555
  let dataFlow = await (0, core_1.__)(Flow_1.default.findOne(params.flowId));
514
556
  if (dataFlow) {
515
557
  if (dataFlow.status === 'off') {
516
- await this.validateFlow(params.flowId, manager);
558
+ await this.validateFlow(params.flowId, manager, 'on');
517
559
  //change to active
518
560
  dataFlow.status = 'on';
519
561
  }
520
562
  else {
563
+ await this.validateFlow(params.flowId, manager, 'off');
521
564
  dataFlow.status = 'off';
522
565
  }
523
566
  dataFlow.modifiedAt = new Date();
@@ -529,45 +572,77 @@ let Flow = class Flow extends core_1.Controller {
529
572
  return { success: false };
530
573
  }
531
574
  }
532
- async validateFlow(flowId, manager) {
533
- const nodes = await Node_1.default.find({ flowId, isActive: true });
534
- let res = '';
535
- if (nodes.length < 2) {
536
- throw new core_1.PxpError(400, 'Your flow must have at least 2 steps. Please finish configuring it before start');
537
- }
538
- for (const node of nodes) {
539
- const configActionType = !node.action.actionType.schemaJson ? {} : JSON.parse(node.action.actionType.schemaJson);
540
- const configAction = !node.action.schemaJson ? {} : JSON.parse(node.action.schemaJson);
541
- const config = _.merge({}, configActionType, configAction);
542
- const required = [];
543
- for (const key in config) {
544
- if (config.hasOwnProperty(key)) {
545
- const prop = config[key];
546
- if (prop && typeof prop === "object" &&
547
- ((prop.validate && prop.validate.shape.includes('required')) ||
548
- (prop.formComponent && prop.formComponent.validate && prop.formComponent.validate.shape.includes('required')))) {
549
- required.push(key);
575
+ async validateFlow(flowId, manager, status) {
576
+ if (status == 'on') {
577
+ const nodes = await Node_1.default.find({ flowId, isActive: true });
578
+ let res = '';
579
+ if (nodes.length < 2) {
580
+ throw new core_1.PxpError(400, 'Your flow must have at least 2 steps. Please finish configuring it before start');
581
+ }
582
+ for (const node of nodes) {
583
+ const configActionType = !node.action.actionType.schemaJson ? {} : JSON.parse(node.action.actionType.schemaJson);
584
+ const configAction = !node.action.schemaJson ? {} : JSON.parse(node.action.schemaJson);
585
+ const config = _.merge({}, configActionType, configAction);
586
+ const required = [];
587
+ for (const key in config) {
588
+ if (config.hasOwnProperty(key)) {
589
+ const prop = config[key];
590
+ if (prop && typeof prop === "object" &&
591
+ ((prop.validate && prop.validate.shape.includes('required')) ||
592
+ (prop.formComponent && prop.formComponent.validate && prop.formComponent.validate.shape.includes('required')))) {
593
+ required.push(key);
594
+ }
550
595
  }
551
596
  }
552
- }
553
- const valueNode = !node.actionConfigJson ? {} : JSON.parse(node.actionConfigJson);
554
- const valueAction = !node.action.configJsonTemplate ? {} : JSON.parse(node.action.configJsonTemplate);
555
- const values = _.merge({}, valueAction, valueNode);
556
- const missingRequired = [];
557
- required.forEach((property) => {
558
- if (!values.hasOwnProperty(property)) {
559
- missingRequired.push(property);
597
+ const valueNode = !node.actionConfigJson ? {} : JSON.parse(node.actionConfigJson);
598
+ const valueAction = !node.action.configJsonTemplate ? {} : JSON.parse(node.action.configJsonTemplate);
599
+ const values = _.merge({}, valueAction, valueNode);
600
+ const missingRequired = [];
601
+ required.forEach((property) => {
602
+ if (!values.hasOwnProperty(property)) {
603
+ missingRequired.push(property);
604
+ }
605
+ });
606
+ if (missingRequired.length > 0) {
607
+ res += `In node ${node.action.name} you have missing fields: ${missingRequired.join(', ')}, `;
560
608
  }
561
- });
562
- if (missingRequired.length > 0) {
563
- res += `In node ${node.action.name} you have missing fields: ${missingRequired.join(', ')}, `;
564
609
  }
610
+ if (res != '') {
611
+ res = res.slice(0, -2);
612
+ throw new core_1.PxpError(400, 'Please resolve these issues before starting the flow: ' + res);
613
+ }
614
+ return true;
565
615
  }
566
- if (res != '') {
567
- res = res.slice(0, -2);
568
- throw new core_1.PxpError(400, 'Please resolve these issues before starting the flow: ' + res);
616
+ else {
617
+ const flowInstances = await FlowInstance_1.default.find({ flowId, isActive: true });
618
+ const validFlowInstances = [];
619
+ for (const flowInstance of flowInstances) {
620
+ if (flowInstance.status != 'processed') {
621
+ validFlowInstances.push(flowInstance.flowInstanceId);
622
+ }
623
+ else {
624
+ let flowInstanceId = flowInstance.flowInstanceId;
625
+ const totalNI = await NodeInstance_1.default.find({ flowInstanceId, isActive: true });
626
+ const nodeInstances = await (0, typeorm_1.getManager)().transaction(async (transactionalEntityManager) => {
627
+ const queryBuilder = transactionalEntityManager.createQueryBuilder(NodeInstance_1.default, 'node_instance');
628
+ queryBuilder
629
+ .where('node_instance.flowInstanceId = :flowInstanceId', { flowInstanceId })
630
+ .andWhere('((node_instance.status IS NULL AND node_instance.schedule = :schedule) OR (node_instance.status = :status AND node_instance.schedule != :schedule))', {
631
+ status: 'executed',
632
+ schedule: '0000-00-00 00:00:00',
633
+ });
634
+ return queryBuilder.getMany();
635
+ });
636
+ if (totalNI.length > nodeInstances.length) {
637
+ validFlowInstances.push(flowInstanceId);
638
+ }
639
+ }
640
+ }
641
+ if (validFlowInstances.length > 0) {
642
+ throw new core_1.PxpError(400, 'Your flow have at least 1 instance active. Please finish it before change off');
643
+ }
644
+ return true;
569
645
  }
570
- return true;
571
646
  }
572
647
  async basicFlowList(params) {
573
648
  const isActive = params._isActive;
@@ -8,6 +8,7 @@
8
8
  * -------------- ----------- -------------- ------------------------------------
9
9
  * 08-Jul-2021 Favio Figueroa Created
10
10
  * 04-Sep-2023 SP08SEP23 Rensi Arteaga add modifiedAt for flows
11
+ * 29-Sep-2023 SP06OCT23 Mercedes Zambrana Add validation when flow is on
11
12
  * ******************************************************************************
12
13
  */
13
14
  import { EntityManager } from 'typeorm';
@@ -9,6 +9,7 @@
9
9
  * -------------- ----------- -------------- ------------------------------------
10
10
  * 08-Jul-2021 Favio Figueroa Created
11
11
  * 04-Sep-2023 SP08SEP23 Rensi Arteaga add modifiedAt for flows
12
+ * 29-Sep-2023 SP06OCT23 Mercedes Zambrana Add validation when flow is on
12
13
  * ******************************************************************************
13
14
  */
14
15
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
@@ -76,27 +77,36 @@ let Node = class Node extends core_1.Controller {
76
77
  Object.entries(params.__metadata).forEach(([nameKey, values]) => {
77
78
  actionConfigJson[nameKey] = `{{ ${values.name} }}`;
78
79
  });
79
- const upd = await (0, core_1.__)(manager.update(Node_1.default, params.nodeId, {
80
- actionConfigJson: JSON.stringify(actionConfigJson),
81
- }));
80
+ let allowChange = false;
82
81
  let dataNode = await (0, core_1.__)(Node_1.default.findOne(params.nodeId));
83
82
  if (dataNode) {
84
83
  let dataFlow = await (0, core_1.__)(Flow_1.default.findOne(dataNode.flowId));
85
84
  if (dataFlow) {
86
- dataFlow.modifiedAt = new Date();
87
- dataFlow.modifiedBy = this.user.username;
88
- await (0, core_1.__)(manager.save(dataFlow));
85
+ if (dataFlow.status != 'on') {
86
+ allowChange = true;
87
+ dataFlow.modifiedAt = new Date();
88
+ dataFlow.modifiedBy = this.user.username;
89
+ await (0, core_1.__)(manager.save(dataFlow));
90
+ }
89
91
  }
90
92
  }
91
- return {
92
- actionConfigJson,
93
- success: true,
94
- nodeId: params.nodeId,
95
- upd
96
- };
93
+ if (allowChange) {
94
+ const upd = await (0, core_1.__)(manager.update(Node_1.default, params.nodeId, {
95
+ actionConfigJson: JSON.stringify(actionConfigJson),
96
+ }));
97
+ return {
98
+ actionConfigJson,
99
+ success: true,
100
+ nodeId: params.nodeId,
101
+ upd,
102
+ msg: `Changes have been saved successfully.`
103
+ };
104
+ }
105
+ else {
106
+ throw new core_1.PxpError(400, 'Please turn off the flow before make a change');
107
+ }
97
108
  }
98
109
  async getParameterizedNode(params, manager) {
99
- console.log('getParameterizedNode llega');
100
110
  lodash_1.default.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
101
111
  const { nodeId, flowId, substitutionsSchemaJson = {} } = params;
102
112
  const tNodeData = (0, core_1.__)(Node_1.default.findOne(nodeId));
@@ -122,11 +132,6 @@ let Node = class Node extends core_1.Controller {
122
132
  tFieldMapData
123
133
  ]);*/
124
134
  const { actionConfigJson, action: { schemaJson, configJsonTemplate, actionType: { schemaJson: schemaJsonFromActionType } } } = nodeData;
125
- console.log('nodeData actionConfigJson', actionConfigJson);
126
- console.log('action schemaJson', schemaJson);
127
- console.log('action configJsonTemplate', configJsonTemplate);
128
- console.log('actionType schemaJsonFromActionType', schemaJsonFromActionType);
129
- console.log('actionType fieldMapData', fieldMapData);
130
135
  const actionConfigJsonObject = actionConfigJson ? JSON.parse(actionConfigJson) : {};
131
136
  const configJsonTemplateObject = configJsonTemplate ? JSON.parse(configJsonTemplate) : {};
132
137
  let schemaJsonFromActionTypeObject = schemaJsonFromActionType ? JSON.parse(lodash_1.default.template(schemaJsonFromActionType)(substitutionsSchemaJson)) : {};
@@ -205,7 +210,6 @@ let Node = class Node extends core_1.Controller {
205
210
  }
206
211
  return undefined;
207
212
  };
208
- console.log('mergeValues', mergeValues);
209
213
  for (const [nameKey, value] of Object.entries(mergeValues)) {
210
214
  if (schemaJsonObject[nameKey]) {
211
215
  const descValue = await (0, core_1.__)(findFieldInConfigForComponent(schemaJsonObject[nameKey], value));
@@ -217,7 +221,7 @@ let Node = class Node extends core_1.Controller {
217
221
  };
218
222
  }
219
223
  }
220
- console.log('111 schemaJsonObject', schemaJsonObject);
224
+ //console.log('111 schemaJsonObject',schemaJsonObject)
221
225
  /*Object.entries(schemaJsonObject)
222
226
  .filter(([, value]: [nameKey: string, value: any]) => value.initialValue === undefined && value.fromFieldMap === undefined && value.fieldMappingType)
223
227
  .forEach(([nameKey]) => {
@@ -227,7 +231,7 @@ let Node = class Node extends core_1.Controller {
227
231
  ...(hasUniqueByTypeInMappingData && { fromFieldMap: true, ...hasUniqueByTypeInMappingData }),
228
232
  };
229
233
  })*/
230
- console.log('222 schemaJsonObject', schemaJsonObject);
234
+ // console.log('222 schemaJsonObject',schemaJsonObject)
231
235
  return {
232
236
  actionConfigJsonObject,
233
237
  configJsonTemplateObject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pxp-nd/flow",
3
- "version": "1.0.76",
3
+ "version": "1.0.77",
4
4
  "description": "Workflow module for pxp-nd framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",