rez_core 2.3.2 → 2.3.4

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.
Files changed (76) hide show
  1. package/dist/app.module.js +2 -0
  2. package/dist/app.module.js.map +1 -1
  3. package/dist/module/integration/controller/integration.controller.d.ts +8 -1
  4. package/dist/module/integration/controller/integration.controller.js +22 -0
  5. package/dist/module/integration/controller/integration.controller.js.map +1 -1
  6. package/dist/module/integration/dto/create-config.dto.d.ts +7 -0
  7. package/dist/module/integration/dto/create-config.dto.js +29 -1
  8. package/dist/module/integration/dto/create-config.dto.js.map +1 -1
  9. package/dist/module/integration/factories/sms.factory.d.ts +9 -1
  10. package/dist/module/integration/factories/sms.factory.js +36 -4
  11. package/dist/module/integration/factories/sms.factory.js.map +1 -1
  12. package/dist/module/integration/integration.module.js +6 -0
  13. package/dist/module/integration/integration.module.js.map +1 -1
  14. package/dist/module/integration/service/integration.service.d.ts +7 -0
  15. package/dist/module/integration/service/integration.service.js +51 -0
  16. package/dist/module/integration/service/integration.service.js.map +1 -1
  17. package/dist/module/integration/strategies/sms/gupshup-sms.strategy.d.ts +9 -0
  18. package/dist/module/integration/strategies/sms/gupshup-sms.strategy.js +104 -0
  19. package/dist/module/integration/strategies/sms/gupshup-sms.strategy.js.map +1 -0
  20. package/dist/module/integration/strategies/sms/msg91-sms.strategy.d.ts +9 -0
  21. package/dist/module/integration/strategies/sms/msg91-sms.strategy.js +113 -0
  22. package/dist/module/integration/strategies/sms/msg91-sms.strategy.js.map +1 -0
  23. package/dist/module/integration/strategies/sms/tubelight-sms.strategy.d.ts +9 -0
  24. package/dist/module/integration/strategies/sms/tubelight-sms.strategy.js +109 -0
  25. package/dist/module/integration/strategies/sms/tubelight-sms.strategy.js.map +1 -0
  26. package/dist/module/integration/strategies/telephone/ozonetel-voice.strategy.d.ts +7 -2
  27. package/dist/module/integration/strategies/telephone/ozonetel-voice.strategy.js +52 -5
  28. package/dist/module/integration/strategies/telephone/ozonetel-voice.strategy.js.map +1 -1
  29. package/dist/module/mapper/controller/field-mapper.controller.d.ts +6 -0
  30. package/dist/module/mapper/controller/field-mapper.controller.js +45 -0
  31. package/dist/module/mapper/controller/field-mapper.controller.js.map +1 -0
  32. package/dist/module/mapper/dto/field-mapper.dto.d.ts +11 -0
  33. package/dist/module/mapper/dto/field-mapper.dto.js +8 -0
  34. package/dist/module/mapper/dto/field-mapper.dto.js.map +1 -0
  35. package/dist/module/mapper/entity/field-lovs.entity.d.ts +7 -0
  36. package/dist/module/mapper/entity/field-lovs.entity.js +38 -0
  37. package/dist/module/mapper/entity/field-lovs.entity.js.map +1 -0
  38. package/dist/module/mapper/entity/field-mapper.entity.d.ts +12 -0
  39. package/dist/module/mapper/entity/field-mapper.entity.js +58 -0
  40. package/dist/module/mapper/entity/field-mapper.entity.js.map +1 -0
  41. package/dist/module/mapper/mapper.module.d.ts +2 -0
  42. package/dist/module/mapper/mapper.module.js +38 -0
  43. package/dist/module/mapper/mapper.module.js.map +1 -0
  44. package/dist/module/mapper/repository/field-lovs.repository.d.ts +8 -0
  45. package/dist/module/mapper/repository/field-lovs.repository.js +41 -0
  46. package/dist/module/mapper/repository/field-lovs.repository.js.map +1 -0
  47. package/dist/module/mapper/repository/field-mapper.repository.d.ts +9 -0
  48. package/dist/module/mapper/repository/field-mapper.repository.js +42 -0
  49. package/dist/module/mapper/repository/field-mapper.repository.js.map +1 -0
  50. package/dist/module/mapper/service/field-mapper.service.d.ts +16 -0
  51. package/dist/module/mapper/service/field-mapper.service.js +92 -0
  52. package/dist/module/mapper/service/field-mapper.service.js.map +1 -0
  53. package/dist/module/workflow/entity/action.entity.d.ts +2 -0
  54. package/dist/module/workflow/entity/action.entity.js +8 -0
  55. package/dist/module/workflow/entity/action.entity.js.map +1 -1
  56. package/dist/tsconfig.build.tsbuildinfo +1 -1
  57. package/package.json +1 -1
  58. package/src/app.module.ts +2 -0
  59. package/src/module/integration/controller/integration.controller.ts +24 -0
  60. package/src/module/integration/dto/create-config.dto.ts +22 -0
  61. package/src/module/integration/factories/sms.factory.ts +39 -6
  62. package/src/module/integration/integration.module.ts +10 -0
  63. package/src/module/integration/service/integration.service.ts +107 -0
  64. package/src/module/integration/strategies/sms/gupshup-sms.strategy.ts +146 -0
  65. package/src/module/integration/strategies/sms/msg91-sms.strategy.ts +164 -0
  66. package/src/module/integration/strategies/sms/tubelight-sms.strategy.ts +163 -0
  67. package/src/module/integration/strategies/telephone/ozonetel-voice.strategy.ts +80 -7
  68. package/src/module/mapper/controller/field-mapper.controller.ts +19 -0
  69. package/src/module/mapper/dto/field-mapper.dto.ts +14 -0
  70. package/src/module/mapper/entity/field-lovs.entity.ts +21 -0
  71. package/src/module/mapper/entity/field-mapper.entity.ts +36 -0
  72. package/src/module/mapper/mapper.module.ts +26 -0
  73. package/src/module/mapper/repository/field-lovs.repository.ts +22 -0
  74. package/src/module/mapper/repository/field-mapper.repository.ts +27 -0
  75. package/src/module/mapper/service/field-mapper.service.ts +91 -0
  76. package/src/module/workflow/entity/action.entity.ts +6 -0
@@ -0,0 +1,163 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import axios, { AxiosResponse } from 'axios';
3
+ import {
4
+ IntegrationStrategy,
5
+ IntegrationResult,
6
+ } from '../integration.strategy';
7
+
8
+ interface TubelightSmsConfig {
9
+ userName: string;
10
+ password: string;
11
+ tenantId: string;
12
+ sourceNumber: string;
13
+ baseUrl?: string;
14
+ senderId?: string;
15
+ dltTemplateId?: string;
16
+ }
17
+
18
+ interface TubelightSmsApiResponse {
19
+ status: string;
20
+ statusCode?: number;
21
+ messageId?: string;
22
+ data?: {
23
+ messageId: string;
24
+ status: string;
25
+ };
26
+ message?: string;
27
+ error?: string;
28
+ }
29
+
30
+ @Injectable()
31
+ export class TubelightSmsStrategy implements IntegrationStrategy {
32
+ private readonly logger = new Logger(TubelightSmsStrategy.name);
33
+ private readonly defaultBaseUrl = 'https://portal.tubelightcommunications.com/sms/api/v1';
34
+
35
+ async sendMessage(
36
+ to: string,
37
+ message: string,
38
+ config: any,
39
+ ): Promise<IntegrationResult> {
40
+ try {
41
+ if (!this.validateConfig(config)) {
42
+ throw new Error('Invalid Tubelight SMS configuration');
43
+ }
44
+
45
+ const tubelightConfig = config as TubelightSmsConfig;
46
+ const baseUrl = tubelightConfig.baseUrl || this.defaultBaseUrl;
47
+ const url = `${baseUrl}/send`;
48
+
49
+ // Create Basic Auth token
50
+ const authToken = Buffer.from(
51
+ `${tubelightConfig.userName}:${tubelightConfig.password}`,
52
+ ).toString('base64');
53
+
54
+ const payload = {
55
+ tenantId: tubelightConfig.tenantId,
56
+ from: tubelightConfig.senderId || tubelightConfig.sourceNumber,
57
+ to: this.formatPhoneNumber(to),
58
+ message: message,
59
+ dltTemplateId: tubelightConfig.dltTemplateId,
60
+ };
61
+
62
+ const response: AxiosResponse<TubelightSmsApiResponse> = await axios.post(
63
+ url,
64
+ payload,
65
+ {
66
+ headers: {
67
+ Authorization: `Basic ${authToken}`,
68
+ 'Content-Type': 'application/json',
69
+ },
70
+ timeout: 30000,
71
+ },
72
+ );
73
+
74
+ if (
75
+ response.data?.status === 'success' ||
76
+ response.data?.statusCode === 200 ||
77
+ response.data?.data?.status === 'sent'
78
+ ) {
79
+ const messageId =
80
+ response.data?.messageId ||
81
+ response.data?.data?.messageId ||
82
+ new Date().getTime().toString();
83
+
84
+ this.logger.log(
85
+ `Tubelight SMS sent successfully to ${to}, messageId: ${messageId}`,
86
+ );
87
+
88
+ return {
89
+ success: true,
90
+ messageId: messageId,
91
+ provider: 'tubelight',
92
+ service: 'SMS',
93
+ timestamp: new Date(),
94
+ };
95
+ } else {
96
+ throw new Error(
97
+ response.data?.error ||
98
+ response.data?.message ||
99
+ 'Failed to send SMS via Tubelight',
100
+ );
101
+ }
102
+ } catch (error) {
103
+ this.logger.error(
104
+ `Failed to send Tubelight SMS to ${to}`,
105
+ error.response?.data || error.message,
106
+ );
107
+
108
+ return {
109
+ success: false,
110
+ provider: 'tubelight',
111
+ service: 'SMS',
112
+ error: this.extractErrorMessage(error),
113
+ timestamp: new Date(),
114
+ };
115
+ }
116
+ }
117
+
118
+ private formatPhoneNumber(phoneNumber: string): string {
119
+ // Remove any non-digit characters except +
120
+ let formatted = phoneNumber.replace(/[^\d+]/g, '');
121
+
122
+ // Ensure it has + prefix
123
+ if (!formatted.startsWith('+')) {
124
+ formatted = `+${formatted}`;
125
+ }
126
+
127
+ return formatted;
128
+ }
129
+
130
+ private extractErrorMessage(error: any): string {
131
+ if (error.response?.data?.error) {
132
+ return error.response.data.error;
133
+ }
134
+
135
+ if (error.response?.data?.message) {
136
+ return error.response.data.message;
137
+ }
138
+
139
+ if (error.message) {
140
+ return error.message;
141
+ }
142
+
143
+ return 'Unknown Tubelight SMS API error';
144
+ }
145
+
146
+ validateConfig(config: any): boolean {
147
+ if (!config || typeof config !== 'object') {
148
+ return false;
149
+ }
150
+
151
+ // Required fields
152
+ if (
153
+ !config.userName ||
154
+ !config.password ||
155
+ !config.tenantId ||
156
+ !config.sourceNumber
157
+ ) {
158
+ return false;
159
+ }
160
+
161
+ return true;
162
+ }
163
+ }
@@ -16,6 +16,19 @@ interface OzonetelVoiceConfig {
16
16
  external_user_id?: string;
17
17
  }
18
18
 
19
+ interface AgentDetailsResponse {
20
+ status: string;
21
+ message: Array<{
22
+ AgentId: string;
23
+ AgentName: string;
24
+ State: string;
25
+ PhoneNumber: string;
26
+ Skill: string;
27
+ Mode: string;
28
+ Since: string;
29
+ }>;
30
+ }
31
+
19
32
  @Injectable()
20
33
  export class OzonetelVoiceStrategy implements IntegrationStrategy {
21
34
  private readonly baseUrl = 'https://in1-ccaas-api.ozonetel.com';
@@ -49,6 +62,19 @@ export class OzonetelVoiceStrategy implements IntegrationStrategy {
49
62
  };
50
63
  }
51
64
 
65
+ // Check agent status before making the call
66
+ const agentStatus = await this.checkAgentStatus(config, token);
67
+ if (!agentStatus.isReady) {
68
+ return {
69
+ success: false,
70
+ provider: 'ozonetel',
71
+ service: 'THIRD_PARTY',
72
+ error: agentStatus.error ||
73
+ `Agent is not ready. Current state: ${agentStatus.state || 'Unknown'}. Please login to your agent dashboard.`,
74
+ timestamp: new Date(),
75
+ };
76
+ }
77
+
52
78
  // Then make the manual dial call
53
79
  const url = `${this.baseUrl}/ca_apis/AgentManualDial`;
54
80
 
@@ -56,7 +82,7 @@ export class OzonetelVoiceStrategy implements IntegrationStrategy {
56
82
  url,
57
83
  {
58
84
  userName: config.userName,
59
- agentID: config.external_user_id || config.agentID,
85
+ agentID: config.external_user_id,
60
86
  campaignName: config.campaignName, // Always from config
61
87
  customerNumber: to,
62
88
  UCID: true,
@@ -95,7 +121,7 @@ export class OzonetelVoiceStrategy implements IntegrationStrategy {
95
121
  }
96
122
  }
97
123
 
98
- private async generateToken(
124
+ async generateToken(
99
125
  config: OzonetelVoiceConfig,
100
126
  ): Promise<string | null> {
101
127
  try {
@@ -121,6 +147,53 @@ export class OzonetelVoiceStrategy implements IntegrationStrategy {
121
147
  }
122
148
  }
123
149
 
150
+ async checkAgentStatus(
151
+ config: OzonetelVoiceConfig,
152
+ token: string,
153
+ ): Promise<{ isReady: boolean; state?: string; error?: string }> {
154
+ try {
155
+ const url = `${this.baseUrl}/ca_apis/AgentDetails`;
156
+
157
+ const response = await axios.post<AgentDetailsResponse>(
158
+ url,
159
+ {
160
+ userName: config.userName,
161
+ agentId: config.external_user_id,
162
+ },
163
+ {
164
+ headers: {
165
+ apiKey: config.apiKey,
166
+ 'Content-Type': 'application/json',
167
+ Authorization: `Bearer ${token}`,
168
+ },
169
+ },
170
+ );
171
+
172
+ if (response.data?.status === 'success' && response.data?.message?.length > 0) {
173
+ const agentInfo = response.data.message[0];
174
+ const isReady = agentInfo.State?.toUpperCase() === 'READY';
175
+
176
+ return {
177
+ isReady,
178
+ state: agentInfo.State,
179
+ };
180
+ }
181
+
182
+ return {
183
+ isReady: false,
184
+ error: 'Failed to retrieve agent details',
185
+ };
186
+ } catch (error) {
187
+ console.error('Failed to check agent status:', error);
188
+ return {
189
+ isReady: false,
190
+ error: axios.isAxiosError(error)
191
+ ? error.response?.data?.message || error.message
192
+ : 'Unknown error checking agent status',
193
+ };
194
+ }
195
+ }
196
+
124
197
  validateConfig(config: Partial<OzonetelVoiceConfig>): boolean {
125
198
  return !!(
126
199
  config &&
@@ -133,24 +206,24 @@ export class OzonetelVoiceStrategy implements IntegrationStrategy {
133
206
  /**
134
207
  * Create configuration with user agent data merged with admin credentials
135
208
  * Admin credentials (apiKey, userName, campaignName) stay in base config
136
- * Only agent-specific info (agentID) comes from user integration
209
+ * Only agent-specific info (external_user_id) comes from user integration
137
210
  */
138
211
  createUserSpecificConfig(
139
212
  baseConfig: Pick<
140
213
  OzonetelVoiceConfig,
141
214
  'apiKey' | 'userName' | 'campaignName' | 'agentLoginUrl'
142
215
  >,
143
- userIntegrationData?: any,
216
+ externalUserId?: string,
144
217
  ): OzonetelVoiceConfig {
145
- if (!userIntegrationData) {
218
+ if (!externalUserId) {
146
219
  throw new Error(
147
- 'User integration data is required for Ozonetel voice calls',
220
+ 'External user ID is required for Ozonetel voice calls',
148
221
  );
149
222
  }
150
223
 
151
224
  return {
152
225
  ...baseConfig,
153
- agentID: userIntegrationData.agentId,
226
+ external_user_id: externalUserId,
154
227
  };
155
228
  }
156
229
  }
@@ -0,0 +1,19 @@
1
+ import { Controller, Inject, Post, Query, Req, UseGuards } from '@nestjs/common';
2
+ import { FieldMapperService } from '../service/field-mapper.service';
3
+ import { JwtAuthGuard } from '../../auth/guards/jwt.guard';
4
+
5
+ @Controller('field-mapper')
6
+ export class FieldMapperController {
7
+ constructor(@Inject('FieldMapperService') private readonly fieldMapperService: FieldMapperService) {
8
+ }
9
+
10
+ @Post('resolve')
11
+ @UseGuards(JwtAuthGuard)
12
+ async resolve(@Req() req: any, @Query('integration_component') integration_component: string,
13
+ @Query('parent_type') parent_type: string,
14
+ @Query('parent_id') parent_id: number) {
15
+ const loggedInUser = req.user.userData;
16
+ return this.fieldMapperService.resolveData(integration_component, parent_type, parent_id, loggedInUser);
17
+ }
18
+
19
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseEntity } from '../../meta/entity/base-entity.entity';
2
+
3
+ export class FieldMapperDto extends BaseEntity {
4
+ integration_component: string;
5
+ action: string;
6
+ source_attribute: string;
7
+ destination_attribute: string;
8
+ destination_entity_type: string;
9
+ mapped_entity_type: string;
10
+ filter_code?: string;
11
+ filter_json?: any;
12
+
13
+ }
14
+
@@ -0,0 +1,21 @@
1
+ import { Column, Entity } from 'typeorm';
2
+ import { BaseEntity } from '../../meta/entity/base-entity.entity';
3
+
4
+ @Entity({ name: 'cr_field_lov_mapper' })
5
+ export class FieldLovMapper extends BaseEntity {
6
+
7
+ constructor() {
8
+ super();
9
+ this.entity_type = 'FLOV';
10
+ }
11
+
12
+ @Column({ name: 'mapper_field_id'})
13
+ mapper_field_id: number; //1
14
+
15
+ @Column({ name: 'destination_attribute_value', type: 'varchar', length: 30 })
16
+ destination_attribute_value: string; //INDIA
17
+
18
+ @Column({ name: 'source_attribute_value', type: 'varchar', length: 30 })
19
+ source_attribute_value: string; //IND
20
+
21
+ }
@@ -0,0 +1,36 @@
1
+ import { Column, Entity } from 'typeorm';
2
+ import { BaseEntity } from '../../meta/entity/base-entity.entity';
3
+
4
+ @Entity({ name: 'cr_field_mapper' })
5
+ export class FieldMapper extends BaseEntity {
6
+
7
+ constructor() {
8
+ super();
9
+ this.entity_type = 'FMAP';
10
+ }
11
+
12
+ @Column({ name: 'integration_component', type: 'varchar', length: 30 })
13
+ integration_component: string;
14
+
15
+ @Column({ name: 'action', type: 'varchar', length: 30 })
16
+ action: string;
17
+
18
+ @Column({ name: 'source_attribute', type: 'varchar', length: 30 })
19
+ source_attribute: string;
20
+
21
+ @Column({ name: 'destination_attribute', type: 'varchar', length: 30 })
22
+ destination_attribute: string;
23
+
24
+ @Column({ name: 'destination_entity_type', type: 'varchar', length: 30 })
25
+ destination_entity_type: string;
26
+
27
+ @Column({ name: 'mapped_entity_type', type: 'varchar', length: 30, nullable: true })
28
+ mapped_entity_type: string;
29
+
30
+ @Column({ name: 'filter_code', type: 'varchar', length: 30, default: 'default' })
31
+ filter_code: string;
32
+
33
+ @Column({ name: 'is_lov_present', type: 'tinyint' })
34
+ is_lov_present: number;
35
+
36
+ }
@@ -0,0 +1,26 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { TypeOrmModule } from '@nestjs/typeorm';
3
+ import { FieldMapper } from './entity/field-mapper.entity';
4
+ import { FieldMapperService } from './service/field-mapper.service';
5
+ import { FieldMapperRepository } from './repository/field-mapper.repository';
6
+ import { FilterModule } from '../filter/filter.module';
7
+ import { EntityModule } from '../meta/entity.module';
8
+ import { FieldMapperController } from './controller/field-mapper.controller';
9
+ import { FieldLovMapper } from './entity/field-lovs.entity';
10
+ import { FieldLovsRepository } from './repository/field-lovs.repository';
11
+
12
+ @Module({
13
+ imports: [
14
+ TypeOrmModule.forFeature([FieldMapper, FieldLovMapper]),
15
+ FilterModule,
16
+ EntityModule,
17
+ ],
18
+ providers: [
19
+ { provide: 'FieldMapperService', useClass: FieldMapperService },
20
+ FieldMapperRepository,
21
+ FieldLovsRepository,
22
+ ],
23
+ controllers: [FieldMapperController],
24
+ })
25
+ export class MapperModule {
26
+ }
@@ -0,0 +1,22 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectRepository } from '@nestjs/typeorm';
3
+ import { FieldLovMapper } from '../entity/field-lovs.entity';
4
+ import { Repository } from 'typeorm';
5
+
6
+ @Injectable()
7
+ export class FieldLovsRepository {
8
+ constructor(@InjectRepository(FieldLovMapper) private readonly fieldLovMapperRepository: Repository<FieldLovMapper>) {
9
+ }
10
+
11
+ async findByMapperFieldIdAndSourceAttributeValue(mapper_field_id: number, source_attribute_value: string) {
12
+ return await this.fieldLovMapperRepository.findOne({
13
+ where: { mapper_field_id, source_attribute_value },
14
+ });
15
+ }
16
+
17
+ async findByMapperFieldIdAndDestinationAttributeValue(mapper_field_id: number, destination_attribute_value: string) {
18
+ return await this.fieldLovMapperRepository.findOne({
19
+ where: { mapper_field_id, destination_attribute_value },
20
+ })
21
+ }
22
+ }
@@ -0,0 +1,27 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectRepository } from '@nestjs/typeorm';
3
+ import { FieldMapper } from '../entity/field-mapper.entity';
4
+ import { Repository } from 'typeorm';
5
+
6
+ @Injectable()
7
+ export class FieldMapperRepository {
8
+ constructor(
9
+ @InjectRepository(FieldMapper)
10
+ private readonly fieldMapperRepository: Repository<FieldMapper>,
11
+ ) {
12
+ }
13
+
14
+ async findByIntegrationComponentAndDestinationEntityType(integrationComponent: string, destinationEntityType: string) {
15
+ return await this.fieldMapperRepository.find({
16
+ where: { integration_component: integrationComponent, destination_entity_type: destinationEntityType },
17
+ });
18
+ }
19
+
20
+ async save(dto: Partial<FieldMapper>) {
21
+ return await this.fieldMapperRepository.save(dto);
22
+ }
23
+
24
+ async saveBulk(dtos: Partial<FieldMapper>[]) {
25
+ return await this.fieldMapperRepository.save(dtos);
26
+ }
27
+ }
@@ -0,0 +1,91 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { FieldMapperRepository } from '../repository/field-mapper.repository';
3
+ import { FieldMapperDto } from '../dto/field-mapper.dto';
4
+ import { EntityServiceImpl } from '../../meta/service/entity-service-impl.service';
5
+ import { UserData } from '../../user/entity/user.entity';
6
+ import { SavedFilterService } from '../../filter/service/saved-filter.service';
7
+ import { FieldLovsRepository } from '../repository/field-lovs.repository';
8
+
9
+ @Injectable()
10
+ export class FieldMapperService extends EntityServiceImpl {
11
+ constructor(
12
+ private readonly fieldMapperRepository: FieldMapperRepository,
13
+ @Inject('SavedFilterService') private readonly savedFilterService: SavedFilterService,
14
+ private readonly fieldLovsRepository: FieldLovsRepository,
15
+ ) {
16
+ super();
17
+ }
18
+
19
+ async createEntity(dto: FieldMapperDto, loggedInUser: UserData) {
20
+ if (dto.filter_json) {
21
+ const savedFilter = await this.savedFilterService.createEntity(dto.filter_json, loggedInUser);
22
+ dto.filter_code = savedFilter.code;
23
+ }
24
+ return super.createEntity(dto, loggedInUser);
25
+ }
26
+
27
+ async updateEntity(dto: FieldMapperDto, loggedInUser: UserData) {
28
+ if (dto.filter_json) {
29
+ const savedFilter = await this.savedFilterService.createEntity(dto.filter_json, loggedInUser);
30
+ dto.filter_code = savedFilter.code;
31
+ }
32
+ return super.updateEntity(dto, loggedInUser);
33
+ }
34
+
35
+ async createFieldMappers(dtos: FieldMapperDto[]) {
36
+ return await this.fieldMapperRepository.saveBulk(dtos);
37
+ }
38
+
39
+ async resolveData(
40
+ integration_component: string,
41
+ parent_type: string,
42
+ parent_id: number,
43
+ userData: UserData,
44
+ ) {
45
+ const fieldMappers =
46
+ await this.fieldMapperRepository.findByIntegrationComponentAndDestinationEntityType(
47
+ integration_component,
48
+ parent_type,
49
+ );
50
+ const result: Record<string, any> = {};
51
+
52
+ const inMemory: Record<string, Record<string, any>> = {};
53
+
54
+ for (const field of fieldMappers) {
55
+ const entityType = field.mapped_entity_type ? field.mapped_entity_type : field.destination_entity_type;
56
+ const filterCode = field.filter_code || 'default';
57
+ if (!inMemory[entityType]) {
58
+ inMemory[entityType] = {};
59
+ }
60
+ if (!inMemory[entityType][filterCode] && !field.mapped_entity_type) {
61
+ inMemory[entityType][filterCode] = await super.getResolvedEntityData(
62
+ entityType,
63
+ parent_id,
64
+ userData,
65
+ );
66
+ } else {
67
+ // TODO: Handle mapped_entity_type with filterCode
68
+ inMemory[entityType][filterCode] = {};
69
+ }
70
+ const entityData = inMemory[entityType][filterCode];
71
+ if (entityData) {
72
+ let value = entityData[field.destination_attribute];
73
+ if (field.is_lov_present) {
74
+ if (field.action === 'LOOKUP') {
75
+ let fieldLovMapper = await this.fieldLovsRepository.findByMapperFieldIdAndDestinationAttributeValue(field.id, value);
76
+ if (fieldLovMapper) {
77
+ value = fieldLovMapper.source_attribute_value;
78
+ }
79
+ } else {
80
+ let fieldLovMapper = await this.fieldLovsRepository.findByMapperFieldIdAndSourceAttributeValue(field.id, value);
81
+ if (fieldLovMapper) {
82
+ value = fieldLovMapper.destination_attribute_value;
83
+ }
84
+ }
85
+ }
86
+ result[field.source_attribute] = value;
87
+ }
88
+ }
89
+ return result;
90
+ }
91
+ }
@@ -41,4 +41,10 @@ export class ActionEntity extends BaseEntity {
41
41
 
42
42
  @Column({ type: 'int', nullable: true })
43
43
  dependent_action_id: number;
44
+
45
+ @Column({ type: 'varchar', nullable: true })
46
+ mode: string;
47
+
48
+ @Column({ type: 'varchar', nullable: true })
49
+ template: string;
44
50
  }