rez_core 4.0.5 → 4.0.8
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/.vscode/extensions.json +5 -0
- package/dist/module/integration/service/integration.service.d.ts +6 -1
- package/dist/module/integration/service/integration.service.js +13 -7
- package/dist/module/integration/service/integration.service.js.map +1 -1
- package/dist/module/meta/controller/media.controller.d.ts +8 -1
- package/dist/module/meta/controller/media.controller.js +5 -8
- package/dist/module/meta/controller/media.controller.js.map +1 -1
- package/dist/module/meta/service/media-data.service.d.ts +6 -4
- package/dist/module/meta/service/media-data.service.js +144 -17
- package/dist/module/meta/service/media-data.service.js.map +1 -1
- package/dist/module/meta/service/view-master.service.js +1 -1
- package/dist/module/meta/service/view-master.service.js.map +1 -1
- package/dist/module/notification/controller/otp.controller.d.ts +9 -0
- package/dist/module/notification/service/otp.service.d.ts +9 -0
- package/dist/module/user/service/login.service.d.ts +18 -0
- package/dist/module/user/service/login.service.js +4 -1
- package/dist/module/user/service/login.service.js.map +1 -1
- package/dist/module/workflow/service/workflow-meta.service.d.ts +3 -1
- package/dist/module/workflow/service/workflow-meta.service.js +14 -4
- package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/integration/service/integration.service.ts +55 -37
- package/src/module/meta/controller/media.controller.ts +21 -6
- package/src/module/meta/service/media-data.service.ts +292 -27
- package/src/module/meta/service/view-master.service.ts +1 -1
- package/src/module/user/service/login.service.ts +4 -4
- package/src/module/workflow/service/workflow-meta.service.ts +27 -0
package/package.json
CHANGED
|
@@ -18,7 +18,10 @@ import {
|
|
|
18
18
|
UpdateUserIntegrationDto,
|
|
19
19
|
} from '../dto/create-config.dto';
|
|
20
20
|
import { FieldMapperService } from '../../mapper/service/field-mapper.service';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
COMM_TEMPLATE,
|
|
23
|
+
ENTITYTYPE_MEDIA,
|
|
24
|
+
} from '../../../constant/global.constant';
|
|
22
25
|
import { EntityServiceImpl } from '../../meta/service/entity-service-impl.service';
|
|
23
26
|
import { MediaDataService } from '../../meta/service/media-data.service';
|
|
24
27
|
import axios from 'axios';
|
|
@@ -90,12 +93,12 @@ export class IntegrationService {
|
|
|
90
93
|
private readonly sendGridApiStrategy: SendGridApiStrategy,
|
|
91
94
|
private readonly configService: ConfigService,
|
|
92
95
|
private readonly mediaService: MediaDataService,
|
|
93
|
-
@Inject('FieldMapperService')
|
|
96
|
+
@Inject('FieldMapperService')
|
|
97
|
+
private readonly fieldMapperService: FieldMapperService,
|
|
94
98
|
private readonly entityService: EntityServiceImpl,
|
|
95
99
|
@Inject(forwardRef(() => IntegrationQueueService))
|
|
96
100
|
private readonly queueService?: IntegrationQueueService,
|
|
97
|
-
) {
|
|
98
|
-
}
|
|
101
|
+
) {}
|
|
99
102
|
|
|
100
103
|
private deriveServiceType(
|
|
101
104
|
integration_type: string,
|
|
@@ -107,15 +110,15 @@ export class IntegrationService {
|
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
async sendMessage({
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
levelId,
|
|
114
|
+
levelType,
|
|
115
|
+
app_code,
|
|
116
|
+
to,
|
|
117
|
+
message,
|
|
118
|
+
mode,
|
|
119
|
+
priority = 1,
|
|
120
|
+
user_id,
|
|
121
|
+
}: SendMessageDto): Promise<IntegrationResult> {
|
|
119
122
|
try {
|
|
120
123
|
// Get active communication configs for the level
|
|
121
124
|
const configs = await this.getActiveConfigs(
|
|
@@ -195,7 +198,9 @@ export class IntegrationService {
|
|
|
195
198
|
.where('config.level_id = :levelId', { levelId })
|
|
196
199
|
.andWhere('config.level_type = :levelType', { levelType })
|
|
197
200
|
.andWhere('config.app_code = :app_code', { app_code })
|
|
198
|
-
.andWhere('config.integration_type = :integration_type', {
|
|
201
|
+
.andWhere('config.integration_type = :integration_type', {
|
|
202
|
+
integration_type,
|
|
203
|
+
})
|
|
199
204
|
.andWhere('config.status = 1')
|
|
200
205
|
.orderBy('config.is_default', 'DESC')
|
|
201
206
|
.addOrderBy('config.priority', 'ASC')
|
|
@@ -706,7 +711,7 @@ export class IntegrationService {
|
|
|
706
711
|
if (configJson?.[field]) {
|
|
707
712
|
safeConfig[
|
|
708
713
|
`has${field.charAt(0).toUpperCase() + field.slice(1)}`
|
|
709
|
-
|
|
714
|
+
] = true;
|
|
710
715
|
}
|
|
711
716
|
});
|
|
712
717
|
|
|
@@ -813,8 +818,9 @@ export class IntegrationService {
|
|
|
813
818
|
const did = config.config_json.did;
|
|
814
819
|
|
|
815
820
|
if (did) {
|
|
816
|
-
|
|
817
|
-
|
|
821
|
+
await this.entityMapperRepository.delete({
|
|
822
|
+
integration_config_id: config.id,
|
|
823
|
+
});
|
|
818
824
|
|
|
819
825
|
const entityMapper = this.entityMapperRepository.create({
|
|
820
826
|
integration_config_id: config.id,
|
|
@@ -964,7 +970,7 @@ export class IntegrationService {
|
|
|
964
970
|
templateId: externalTemplateId,
|
|
965
971
|
variables,
|
|
966
972
|
richText,
|
|
967
|
-
subject
|
|
973
|
+
subject,
|
|
968
974
|
};
|
|
969
975
|
|
|
970
976
|
// Handle user integration if user_id provided
|
|
@@ -1055,7 +1061,7 @@ export class IntegrationService {
|
|
|
1055
1061
|
...enhancedConfig,
|
|
1056
1062
|
templateId: externalTemplateId,
|
|
1057
1063
|
variables,
|
|
1058
|
-
richText
|
|
1064
|
+
richText,
|
|
1059
1065
|
};
|
|
1060
1066
|
|
|
1061
1067
|
// Handle user integration if user_id provided
|
|
@@ -1071,11 +1077,7 @@ export class IntegrationService {
|
|
|
1071
1077
|
}
|
|
1072
1078
|
}
|
|
1073
1079
|
|
|
1074
|
-
const result = await strategy.sendMessage(
|
|
1075
|
-
to,
|
|
1076
|
-
message,
|
|
1077
|
-
finalConfig,
|
|
1078
|
-
);
|
|
1080
|
+
const result = await strategy.sendMessage(to, message, finalConfig);
|
|
1079
1081
|
|
|
1080
1082
|
if (result.success) {
|
|
1081
1083
|
this.logger.log(
|
|
@@ -1291,12 +1293,21 @@ export class IntegrationService {
|
|
|
1291
1293
|
});
|
|
1292
1294
|
}
|
|
1293
1295
|
|
|
1294
|
-
|
|
1296
|
+
public async processTemplate(
|
|
1295
1297
|
templateId: number,
|
|
1296
1298
|
entity_type: any,
|
|
1297
1299
|
entity_id: any,
|
|
1298
|
-
): Promise<{
|
|
1299
|
-
|
|
1300
|
+
): Promise<{
|
|
1301
|
+
variables?: Record<string, any>;
|
|
1302
|
+
externalTemplateId?: string;
|
|
1303
|
+
rich_text?: string;
|
|
1304
|
+
subject?: string;
|
|
1305
|
+
}> {
|
|
1306
|
+
const commTemplate: any = await this.entityService.getEntityData(
|
|
1307
|
+
COMM_TEMPLATE,
|
|
1308
|
+
templateId,
|
|
1309
|
+
{} as any,
|
|
1310
|
+
);
|
|
1300
1311
|
if (!commTemplate) {
|
|
1301
1312
|
return {
|
|
1302
1313
|
variables: {},
|
|
@@ -1308,7 +1319,7 @@ export class IntegrationService {
|
|
|
1308
1319
|
if (commTemplate.mapper_id) {
|
|
1309
1320
|
variables = await this.fieldMapperService.resolveData(
|
|
1310
1321
|
commTemplate.mapper_id,
|
|
1311
|
-
|
|
1322
|
+
'LOOKUP',
|
|
1312
1323
|
entity_type,
|
|
1313
1324
|
entity_id,
|
|
1314
1325
|
{} as any,
|
|
@@ -1320,10 +1331,16 @@ export class IntegrationService {
|
|
|
1320
1331
|
|
|
1321
1332
|
if (!richText) {
|
|
1322
1333
|
if (commTemplate.markup_id) {
|
|
1323
|
-
let url = await this.mediaService.getMediaDownloadUrl(
|
|
1334
|
+
let url = await this.mediaService.getMediaDownloadUrl(
|
|
1335
|
+
commTemplate.markup_id,
|
|
1336
|
+
{},
|
|
1337
|
+
60000,
|
|
1338
|
+
);
|
|
1324
1339
|
if (url) {
|
|
1325
|
-
let response = await axios.get(url.signedUrl, {
|
|
1326
|
-
|
|
1340
|
+
let response = await axios.get(url.signedUrl, {
|
|
1341
|
+
responseType: 'text',
|
|
1342
|
+
});
|
|
1343
|
+
richText = response.data;
|
|
1327
1344
|
}
|
|
1328
1345
|
}
|
|
1329
1346
|
}
|
|
@@ -1335,7 +1352,7 @@ export class IntegrationService {
|
|
|
1335
1352
|
|
|
1336
1353
|
return {
|
|
1337
1354
|
rich_text: richText,
|
|
1338
|
-
subject: commTemplate.subject
|
|
1355
|
+
subject: commTemplate.subject,
|
|
1339
1356
|
};
|
|
1340
1357
|
}
|
|
1341
1358
|
|
|
@@ -2023,10 +2040,10 @@ export class IntegrationService {
|
|
|
2023
2040
|
|
|
2024
2041
|
async getIntegrationConfigById(hubId: number): Promise<
|
|
2025
2042
|
| (IntegrationConfig & {
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2043
|
+
config: IntegrationConfig;
|
|
2044
|
+
linkedSource?: string;
|
|
2045
|
+
configDetails?: any;
|
|
2046
|
+
})
|
|
2030
2047
|
| null
|
|
2031
2048
|
> {
|
|
2032
2049
|
try {
|
|
@@ -2518,7 +2535,8 @@ export class IntegrationService {
|
|
|
2518
2535
|
if (!userIntegration) {
|
|
2519
2536
|
return {
|
|
2520
2537
|
success: false,
|
|
2521
|
-
error:
|
|
2538
|
+
error:
|
|
2539
|
+
'User integration mapping not found. Please configure agent details.',
|
|
2522
2540
|
};
|
|
2523
2541
|
}
|
|
2524
2542
|
|
|
@@ -28,6 +28,8 @@ export class MediaController {
|
|
|
28
28
|
attribute_key: string;
|
|
29
29
|
mapped_entity_type?: string;
|
|
30
30
|
mapped_entity_id?: number;
|
|
31
|
+
parent_id?: number;
|
|
32
|
+
parent_type?: string;
|
|
31
33
|
},
|
|
32
34
|
@Req() req: Request & { user: any },
|
|
33
35
|
@Res() res: Response,
|
|
@@ -40,6 +42,8 @@ export class MediaController {
|
|
|
40
42
|
loggedInUser,
|
|
41
43
|
body.mapped_entity_type,
|
|
42
44
|
body.mapped_entity_id,
|
|
45
|
+
body.parent_id,
|
|
46
|
+
body.parent_type,
|
|
43
47
|
);
|
|
44
48
|
if (result) {
|
|
45
49
|
res.status(HttpStatus.OK).json({
|
|
@@ -81,12 +85,23 @@ export class MediaController {
|
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
@Post('generateUploadPath')
|
|
84
|
-
async generateUploadPath(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
async generateUploadPath(
|
|
89
|
+
@Req() req: Request & { user: any },
|
|
90
|
+
@Body()
|
|
91
|
+
body: {
|
|
92
|
+
mapped_entity_type: string;
|
|
93
|
+
mapped_entity_id?: number;
|
|
94
|
+
parent_id?: number;
|
|
95
|
+
parent_type?: string;
|
|
96
|
+
},
|
|
97
|
+
) {
|
|
89
98
|
const loggedInUser = req.user.userData;
|
|
90
|
-
return this.mediaDataService.buildUploadPathGeneric(
|
|
99
|
+
return this.mediaDataService.buildUploadPathGeneric(
|
|
100
|
+
body.mapped_entity_type,
|
|
101
|
+
loggedInUser,
|
|
102
|
+
body.mapped_entity_id,
|
|
103
|
+
body.parent_id,
|
|
104
|
+
body.parent_type,
|
|
105
|
+
);
|
|
91
106
|
}
|
|
92
107
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { EntityServiceImpl } from './entity-service-impl.service';
|
|
3
|
-
import { MediaDataRepository } from '../repository/media-data.repository';
|
|
4
2
|
import { ConfigService } from '@nestjs/config';
|
|
5
3
|
import { S3 } from 'aws-sdk';
|
|
6
|
-
import
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import { DataSource } from 'typeorm';
|
|
6
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
7
7
|
import {
|
|
8
8
|
ENTITYTYPE_MEDIA,
|
|
9
9
|
STATUS_PENDING,
|
|
10
10
|
} from '../../../constant/global.constant';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { DataSource } from 'typeorm';
|
|
11
|
+
import { MediaData } from '../entity/media-data.entity';
|
|
12
|
+
import { MediaDataRepository } from '../repository/media-data.repository';
|
|
13
|
+
import { EntityServiceImpl } from './entity-service-impl.service';
|
|
15
14
|
|
|
16
15
|
@Injectable()
|
|
17
16
|
export class MediaDataService extends EntityServiceImpl {
|
|
@@ -41,6 +40,8 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
41
40
|
loggedInUser,
|
|
42
41
|
mappedEntityType?: string,
|
|
43
42
|
mappedEntityId?: number,
|
|
43
|
+
parentId?: number,
|
|
44
|
+
parentType?: string,
|
|
44
45
|
) {
|
|
45
46
|
if (!fileName || !mappedAttributeKey) {
|
|
46
47
|
return null;
|
|
@@ -49,8 +50,16 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
49
50
|
|
|
50
51
|
const id = uuidv4();
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
const s3Path =
|
|
54
|
+
(await this.buildUploadPathGeneric(
|
|
55
|
+
mappedEntityType || '',
|
|
56
|
+
loggedInUser,
|
|
57
|
+
mappedEntityId,
|
|
58
|
+
parentId,
|
|
59
|
+
parentType,
|
|
60
|
+
)) || `uploads`;
|
|
61
|
+
|
|
62
|
+
const s3Key = `${s3Path}/${id}.${ext}`;
|
|
54
63
|
|
|
55
64
|
const uploadUrl = await this.s3.getSignedUrlPromise('putObject', {
|
|
56
65
|
Bucket: this.bucketName,
|
|
@@ -71,6 +80,7 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
71
80
|
}
|
|
72
81
|
mediaData.media_url = s3Key;
|
|
73
82
|
|
|
83
|
+
//INSERT RECORD IN DOC TABLE
|
|
74
84
|
const savedEntity = await super.createEntity(mediaData, loggedInUser);
|
|
75
85
|
|
|
76
86
|
if (savedEntity) {
|
|
@@ -134,10 +144,12 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
134
144
|
const mediaData = entityData as MediaData;
|
|
135
145
|
let fileSize: number | undefined;
|
|
136
146
|
if (this.bucketName) {
|
|
137
|
-
const head = await this.s3
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
const head = await this.s3
|
|
148
|
+
.headObject({
|
|
149
|
+
Bucket: this.bucketName,
|
|
150
|
+
Key: mediaData.media_url,
|
|
151
|
+
})
|
|
152
|
+
.promise();
|
|
141
153
|
fileSize = head.ContentLength;
|
|
142
154
|
}
|
|
143
155
|
|
|
@@ -146,14 +158,19 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
146
158
|
Key: mediaData.media_url,
|
|
147
159
|
Expires: Number(expiresIn) || 60 * 5,
|
|
148
160
|
});
|
|
149
|
-
return {
|
|
161
|
+
return {
|
|
162
|
+
signedUrl,
|
|
163
|
+
fileName: mediaData.file_name,
|
|
164
|
+
id: mediaData.id,
|
|
165
|
+
size: fileSize,
|
|
166
|
+
};
|
|
150
167
|
} catch (error) {
|
|
151
168
|
console.error('Error generating signed URL for media:', error);
|
|
152
169
|
throw new Error('Failed to generate signed URL');
|
|
153
170
|
}
|
|
154
171
|
}
|
|
155
172
|
|
|
156
|
-
public async
|
|
173
|
+
public async buildUploadPathGenericdd(
|
|
157
174
|
mappedEntityType: string,
|
|
158
175
|
loggedInUser,
|
|
159
176
|
mappedEntityId?: number,
|
|
@@ -161,7 +178,10 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
161
178
|
parentType?: string,
|
|
162
179
|
) {
|
|
163
180
|
// 1️⃣ Fetch entity metadata
|
|
164
|
-
const entityMaster = await this.entityMasterService.getEntityData(
|
|
181
|
+
const entityMaster = await this.entityMasterService.getEntityData(
|
|
182
|
+
mappedEntityType,
|
|
183
|
+
loggedInUser,
|
|
184
|
+
);
|
|
165
185
|
if (!entityMaster) {
|
|
166
186
|
throw new Error(`Entity master not found for ${mappedEntityType}`);
|
|
167
187
|
}
|
|
@@ -177,17 +197,115 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
177
197
|
const replacements: Record<string, string | null> = {};
|
|
178
198
|
|
|
179
199
|
// --- ORG ---
|
|
180
|
-
let organizationData = await this.dataSource.query(
|
|
200
|
+
let organizationData = await this.dataSource.query(
|
|
201
|
+
'SELECT * FROM sso_organization WHERE id = ?',
|
|
202
|
+
[loggedInUser.organization_id],
|
|
203
|
+
);
|
|
181
204
|
replacements['org_code'] = organizationData[0].code;
|
|
182
205
|
|
|
183
206
|
// --- LEVEL CODE ---
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
207
|
+
// Priority: If parent is provided, use parent for level_code; otherwise use normal logic
|
|
208
|
+
let levelEntityId: number;
|
|
209
|
+
let levelEntityType: string;
|
|
210
|
+
|
|
211
|
+
if (parentId && parentType) {
|
|
212
|
+
// When parent is provided, parent becomes the level_code
|
|
213
|
+
levelEntityId = parentId;
|
|
214
|
+
levelEntityType = parentType;
|
|
215
|
+
} else {
|
|
216
|
+
// Normal logic: determine which entity to use for level_code
|
|
217
|
+
levelEntityId = entityOverwrite ? mappedEntityId : loggedInUser.level_id;
|
|
218
|
+
levelEntityType = entityOverwrite
|
|
219
|
+
? mappedEntityType
|
|
220
|
+
: loggedInUser.level_type;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Get entity data for level_code
|
|
224
|
+
const getEntityData = await this.dataSource.query(
|
|
225
|
+
`SELECT * FROM cr_entity_master WHERE mapped_entity_type = ? and organization_id = ?`,
|
|
226
|
+
[levelEntityType, loggedInUser.organization_id],
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
if (getEntityData.length == 0) return null;
|
|
230
|
+
const levelEntityDataResult = await this.dataSource.query(
|
|
231
|
+
`SELECT * FROM ${getEntityData[0]?.db_table_name} WHERE id = ?`,
|
|
232
|
+
[levelEntityId],
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
const levelEntityData = levelEntityDataResult[0] || null;
|
|
236
|
+
|
|
187
237
|
if (levelEntityData?.code) {
|
|
188
238
|
replacements['level_code'] = levelEntityData.code; // universal alias
|
|
189
239
|
}
|
|
190
240
|
|
|
241
|
+
// --- MAPPED ENTITY CODE (when parent is provided) ---
|
|
242
|
+
// When parent is provided, the mapped entity becomes an additional level
|
|
243
|
+
if (parentId && parentType && mappedEntityId && mappedEntityType) {
|
|
244
|
+
const mappedEntityKey = `${mappedEntityType.toLowerCase()}_code`;
|
|
245
|
+
const mappedEntityData = await super.getEntityData(
|
|
246
|
+
mappedEntityType,
|
|
247
|
+
mappedEntityId,
|
|
248
|
+
loggedInUser,
|
|
249
|
+
);
|
|
250
|
+
if (mappedEntityData?.code) {
|
|
251
|
+
replacements[mappedEntityKey] = mappedEntityData.code;
|
|
252
|
+
|
|
253
|
+
// Modify path template to include mapped entity
|
|
254
|
+
// Example: ${org_code}/${level_code} becomes ${org_code}/${level_code}/${tem_code}
|
|
255
|
+
const mappedVariable = `\${${mappedEntityKey}}`;
|
|
256
|
+
if (!pathTemplate.includes(mappedVariable)) {
|
|
257
|
+
pathTemplate = pathTemplate + `/${mappedVariable}`;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// --- TEMPLATE CODE (if parent is provided) ---
|
|
263
|
+
// Special handling for template_code when parent_id and parent_type are provided
|
|
264
|
+
if (parentId && parentType) {
|
|
265
|
+
// const templateEntityData = await super.getEntityData(
|
|
266
|
+
// parentType,
|
|
267
|
+
// parentId,
|
|
268
|
+
// loggedInUser,
|
|
269
|
+
// );
|
|
270
|
+
|
|
271
|
+
// Get entity data for level_code
|
|
272
|
+
const getEntityData = await this.dataSource.query(
|
|
273
|
+
`SELECT * FROM cr_entity_master WHERE mapped_entity_type = ? and organization_id = ?`,
|
|
274
|
+
[mappedEntityType, loggedInUser.organization_id],
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
if (getEntityData.length == 0) return null;
|
|
278
|
+
const levelEntityDataResult = await this.dataSource.query(
|
|
279
|
+
`SELECT * FROM ${getEntityData[0]?.db_table_name} WHERE id = ?`,
|
|
280
|
+
[mappedEntityId],
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
if (
|
|
284
|
+
levelEntityDataResult?.[0].code &&
|
|
285
|
+
parentType != 'SCH' &&
|
|
286
|
+
loggedInUser.level_type != 'SCH'
|
|
287
|
+
) {
|
|
288
|
+
replacements['template_code'] = levelEntityDataResult[0].code;
|
|
289
|
+
// If we have parent template, modify the path to include it
|
|
290
|
+
pathTemplate = '${org_code}/template/${template_code}';
|
|
291
|
+
} else {
|
|
292
|
+
const getEntityData = await this.dataSource.query(
|
|
293
|
+
`SELECT * FROM cr_entity_master WHERE mapped_entity_type = ? and organization_id = ?`,
|
|
294
|
+
[mappedEntityType, loggedInUser.organization_id],
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
if (getEntityData.length == 0) return null;
|
|
298
|
+
const levelEntityDataResult = await this.dataSource.query(
|
|
299
|
+
`SELECT * FROM ${getEntityData[0]?.db_table_name} WHERE id = ?`,
|
|
300
|
+
[mappedEntityId],
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
replacements['template_code'] = levelEntityDataResult?.[0].code;
|
|
304
|
+
|
|
305
|
+
pathTemplate = '${org_code}/${level_code}/template/${template_code}';
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
191
309
|
// --- Dynamic variables inside path ---
|
|
192
310
|
const matches = pathTemplate.match(/\$\{(\w+)\}/g) || [];
|
|
193
311
|
|
|
@@ -196,29 +314,48 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
196
314
|
if (replacements[key]) continue; // already resolved
|
|
197
315
|
|
|
198
316
|
if (key === 'org_code') continue; // already set
|
|
317
|
+
if (key === 'level_code') continue; // already set above
|
|
318
|
+
if (key === 'template_code') continue; // handled above if parent is provided
|
|
319
|
+
|
|
199
320
|
if (key.endsWith('_code')) {
|
|
200
321
|
// derive entity type dynamically
|
|
201
322
|
const entityType = key.replace('_code', '').toUpperCase();
|
|
202
323
|
|
|
203
324
|
let entityId: number | undefined;
|
|
204
|
-
|
|
205
|
-
|
|
325
|
+
|
|
326
|
+
// Special handling for template_code - use parent if available, otherwise mapped entity
|
|
327
|
+
if (key === 'template_code') {
|
|
328
|
+
if (parentType?.toUpperCase() === 'TEMPLATE' && parentId) {
|
|
329
|
+
entityId = parentId;
|
|
330
|
+
} else if (mappedEntityType === 'TEMPLATE') {
|
|
331
|
+
entityId = mappedEntityId;
|
|
332
|
+
}
|
|
206
333
|
} else {
|
|
207
|
-
|
|
334
|
+
// For other _code variables, check if parent matches the entity type
|
|
335
|
+
if (parentType?.toUpperCase() === entityType && parentId) {
|
|
336
|
+
entityId = parentId;
|
|
337
|
+
} else if (mappedEntityType === entityType) {
|
|
338
|
+
entityId = mappedEntityId;
|
|
339
|
+
}
|
|
208
340
|
}
|
|
209
341
|
|
|
210
342
|
// Generic lookup
|
|
211
343
|
if (entityId) {
|
|
212
|
-
const entityData = await super.getEntityData(
|
|
344
|
+
const entityData = await super.getEntityData(
|
|
345
|
+
entityType,
|
|
346
|
+
entityId,
|
|
347
|
+
loggedInUser,
|
|
348
|
+
);
|
|
213
349
|
replacements[key] = entityData?.code ?? null;
|
|
214
350
|
}
|
|
215
351
|
}
|
|
216
352
|
}
|
|
217
353
|
|
|
218
354
|
// --- ORG special case ---
|
|
219
|
-
// If ORG level & overwrite = 0 →
|
|
355
|
+
// If ORG level & overwrite = 0 → use org_code, otherwise use the mapped entity's code
|
|
220
356
|
if (loggedInUser.level_type === 'ORG' && entityOverwrite === 0) {
|
|
221
|
-
|
|
357
|
+
// When overwrite is 0 and user is ORG level, but we want to use mapped entity
|
|
358
|
+
// Don't set level_code to null - it should already be set above based on entityOverwrite logic
|
|
222
359
|
}
|
|
223
360
|
|
|
224
361
|
// 3️⃣ Final substitution and cleanup
|
|
@@ -229,12 +366,140 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
229
366
|
return null;
|
|
230
367
|
}
|
|
231
368
|
|
|
369
|
+
public async buildUploadPathGeneric(
|
|
370
|
+
mappedEntityType: string,
|
|
371
|
+
loggedInUser,
|
|
372
|
+
mappedEntityId?: number,
|
|
373
|
+
parentId?: number,
|
|
374
|
+
parentType?: string,
|
|
375
|
+
) {
|
|
376
|
+
//APPCODE
|
|
377
|
+
let appCode = '';
|
|
378
|
+
|
|
379
|
+
let org_id = loggedInUser.organization_id;
|
|
380
|
+
let level_type = loggedInUser.level_type;
|
|
381
|
+
let level_id =
|
|
382
|
+
loggedInUser.level_type == 'ORG' && mappedEntityType == 'SCH'
|
|
383
|
+
? mappedEntityId
|
|
384
|
+
: loggedInUser.level_id;
|
|
385
|
+
|
|
386
|
+
let organizationData = {};
|
|
387
|
+
let levelData = {};
|
|
388
|
+
let mappedEntityData = {};
|
|
389
|
+
|
|
390
|
+
if (loggedInUser && loggedInUser.appcode) {
|
|
391
|
+
appCode = loggedInUser.appcode;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (appCode && appCode != 'ADM') {
|
|
395
|
+
const baseUrl = this.configService.get<string>('REDIRECT_BE_URL');
|
|
396
|
+
|
|
397
|
+
// Prepare the query string
|
|
398
|
+
const queryParams = new URLSearchParams({
|
|
399
|
+
loggedInUser: JSON.stringify(loggedInUser),
|
|
400
|
+
}).toString();
|
|
401
|
+
|
|
402
|
+
organizationData = await axios
|
|
403
|
+
.get(`${baseUrl}/organization/public/?${queryParams}`)
|
|
404
|
+
.then((res) => res.data)
|
|
405
|
+
.catch((err) => {
|
|
406
|
+
console.error('Error fetching organization data:', err.message);
|
|
407
|
+
return null;
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
levelData = await axios
|
|
411
|
+
.get(`${baseUrl}/school/public/?${queryParams}`)
|
|
412
|
+
.then((res) => res.data)
|
|
413
|
+
.catch((err) => {
|
|
414
|
+
console.error('Error fetching school data:', err.message);
|
|
415
|
+
return null;
|
|
416
|
+
});
|
|
417
|
+
} else {
|
|
418
|
+
organizationData = await this.dataSource.query(
|
|
419
|
+
'SELECT * FROM adm_org_profile WHERE id = ?',
|
|
420
|
+
[loggedInUser.organization_id],
|
|
421
|
+
);
|
|
422
|
+
levelData = await this.dataSource.query(
|
|
423
|
+
'SELECT * FROM adm_school_profile WHERE id = ?',
|
|
424
|
+
[loggedInUser.level_id],
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
console.log(levelData);
|
|
429
|
+
|
|
430
|
+
// 1️⃣ Fetch entity metadata
|
|
431
|
+
// const uploadEntity = await this.entityMasterService.getEntityData(
|
|
432
|
+
// mappedEntityType,
|
|
433
|
+
// loggedInUser,
|
|
434
|
+
// );
|
|
435
|
+
// if (!uploadEntity) {
|
|
436
|
+
// throw new Error(`Entity master not found for ${mappedEntityType}`);
|
|
437
|
+
// }
|
|
438
|
+
|
|
439
|
+
let subfolder =
|
|
440
|
+
mappedEntityType == level_type
|
|
441
|
+
? 'data'
|
|
442
|
+
: parentType
|
|
443
|
+
? `${parentType}/${parentId}/${mappedEntityType}`
|
|
444
|
+
: mappedEntityType;
|
|
445
|
+
let path =
|
|
446
|
+
'${org_code}/${level_code}/' +
|
|
447
|
+
(subfolder !== 'data'
|
|
448
|
+
? `${subfolder}/${mappedEntityId}`
|
|
449
|
+
: `${subfolder}`);
|
|
450
|
+
|
|
451
|
+
// 2️⃣ Prepare replacement map
|
|
452
|
+
const replacements: Record<string, string | null> = {};
|
|
453
|
+
replacements['org_code'] = organizationData[0]?.code;
|
|
454
|
+
replacements['level_code'] = levelData[0]?.code; // universal alias
|
|
455
|
+
|
|
456
|
+
// 3️⃣ Final substitution and cleanup
|
|
457
|
+
if (path) {
|
|
458
|
+
const finalPath = this.resolveUploadPath(path, replacements);
|
|
459
|
+
return finalPath;
|
|
460
|
+
}
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
|
|
232
464
|
/**
|
|
233
465
|
* Replace placeholders with actual values, remove missing variables
|
|
234
466
|
*/
|
|
235
|
-
private resolveUploadPath(
|
|
467
|
+
private resolveUploadPath(
|
|
468
|
+
template: string,
|
|
469
|
+
replacements: Record<string, string | null>,
|
|
470
|
+
) {
|
|
236
471
|
let path = template;
|
|
237
472
|
path = path.replace(/\$\{(\w+)\}/g, (_, key) => replacements[key] || '');
|
|
238
473
|
return path.replace(/\/+/g, '/').replace(/\/$/, '');
|
|
239
474
|
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Helper method to build upload path for different scenarios
|
|
478
|
+
*
|
|
479
|
+
* @param mappedEntityType - The main entity type (e.g., 'LEAD', 'SCH')
|
|
480
|
+
* @param loggedInUser - Current user context
|
|
481
|
+
* @param mappedEntityId - ID of the main entity
|
|
482
|
+
* @param parentId - Optional parent entity ID (e.g., template ID)
|
|
483
|
+
* @param parentType - Optional parent entity type (e.g., 'TEMPLATE')
|
|
484
|
+
* @returns Promise<string | null> - The resolved upload path
|
|
485
|
+
*
|
|
486
|
+
* Examples:
|
|
487
|
+
* - buildUploadPath('LEAD', user, 123) -> "ORG1/template/SCH1"
|
|
488
|
+
* - buildUploadPath('LEAD', user, 123, 456, 'TEMPLATE') -> "ORG1/template/SCH1/TEMPLATE1"
|
|
489
|
+
*/
|
|
490
|
+
async buildUploadPath(
|
|
491
|
+
mappedEntityType: string,
|
|
492
|
+
loggedInUser: any,
|
|
493
|
+
mappedEntityId?: number,
|
|
494
|
+
parentId?: number,
|
|
495
|
+
parentType?: string,
|
|
496
|
+
): Promise<string | null> {
|
|
497
|
+
return this.buildUploadPathGeneric(
|
|
498
|
+
mappedEntityType,
|
|
499
|
+
loggedInUser,
|
|
500
|
+
mappedEntityId,
|
|
501
|
+
parentId,
|
|
502
|
+
parentType,
|
|
503
|
+
);
|
|
504
|
+
}
|
|
240
505
|
}
|
|
@@ -90,7 +90,7 @@ export class ViewMasterService extends EntityServiceImpl {
|
|
|
90
90
|
|
|
91
91
|
// Make the GET request with query parameters
|
|
92
92
|
const response = await axios.get<any>(
|
|
93
|
-
`${baseUrl}/school/theme_json/${loggedInUserData?.level_id}`,
|
|
93
|
+
`${baseUrl}/school/public/theme_json/${loggedInUserData?.level_id}`,
|
|
94
94
|
|
|
95
95
|
{
|
|
96
96
|
headers: {
|