rez_core 3.1.133 → 3.1.134

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "3.1.133",
3
+ "version": "3.1.134",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -148,14 +148,16 @@ export class WrapperService {
148
148
  async sendCommunicationWrapperService(entity: any, loggedInUser: any) {
149
149
  try {
150
150
  this.logger.log(
151
- `sendCommunicationWrapper called. User: ${JSON.stringify(loggedInUser)}, Payload: ${JSON.stringify(entity)}`,
151
+ `sendCommunicationWrapper called. User: ${JSON.stringify(
152
+ loggedInUser,
153
+ )}, Payload: ${JSON.stringify(entity)}`,
152
154
  );
153
155
 
154
- const { level_id, level_type, appcode } = loggedInUser;
156
+ const { level_id, level_type, appcode, organization_id } = loggedInUser;
155
157
 
156
- // Step 1: Check if active email configs exist for current user's level
158
+ // Check if active configs exist for current user's level
157
159
  this.logger.debug(
158
- `Checking active EMAIL configs for level_id=${level_id}, level_type=${level_type}, app_code=${appcode}`,
160
+ `Checking active ${entity.type || 'EMAIL'} configs for level_id=${level_id}, level_type=${level_type}, app_code=${appcode}`,
159
161
  );
160
162
 
161
163
  let configs = await this.integrationService.getActiveConfigs(
@@ -168,7 +170,7 @@ export class WrapperService {
168
170
  let effectiveLevelId = level_id;
169
171
  let effectiveLevelType = level_type;
170
172
 
171
- // Step 2: If no configs exist, fall back to ORG-level (1, 'ORG')
173
+ // Fallback to ORG-level if no configs found
172
174
  if (!configs || configs.length === 0) {
173
175
  this.logger.warn(
174
176
  `No active configs found for ${level_type}:${level_id}, falling back to ORG-level`,
@@ -180,6 +182,7 @@ export class WrapperService {
180
182
  appcode,
181
183
  entity.type || 'EMAIL',
182
184
  );
185
+
183
186
  effectiveLevelId = 1;
184
187
  effectiveLevelType = 'ORG';
185
188
  }
@@ -189,14 +192,60 @@ export class WrapperService {
189
192
  throw new Error('No active configurations found.');
190
193
  }
191
194
 
192
- // Step 3: Prepare payload for Integration Service
195
+ // Template lookup if templateCode is provided
196
+ let resolvedTemplateId = entity?.templateId;
197
+
198
+ if (entity.template_code) {
199
+ this.logger.debug(
200
+ `Looking up template for code=${entity.template_code}, level_id=${level_id}, level_type=${level_type}`,
201
+ );
202
+
203
+ // Try to find template at user's level first
204
+ let templates = await this.datasource.query(
205
+ `SELECT id FROM cr_wf_comm_template
206
+ WHERE code = ?
207
+ AND level_id = ?
208
+ AND level_type = ?
209
+ LIMIT 1`,
210
+ [entity.template_code, level_id, level_type],
211
+ );
212
+
213
+ // Fallback to ORG + organization_id if not found
214
+ if (!templates || templates.length === 0) {
215
+ this.logger.warn(
216
+ `No template found for ${entity.template_code} at provided level. Falling back to ORG-level.`,
217
+ );
218
+
219
+ templates = await this.datasource.query(
220
+ `SELECT id FROM cr_wf_comm_template
221
+ WHERE code = ?
222
+ AND level_type = 'ORG'
223
+ AND organization_id = ?
224
+ LIMIT 1`,
225
+ [entity.template_code, organization_id],
226
+ );
227
+ }
228
+
229
+ if (templates && templates.length > 0) {
230
+ resolvedTemplateId = templates[0]?.id;
231
+ this.logger.debug(
232
+ `Template resolved for code=${entity.template_code}, id=${resolvedTemplateId}`,
233
+ );
234
+ } else {
235
+ this.logger.warn(
236
+ `No template found for code=${entity.template_code} at any level.`,
237
+ );
238
+ }
239
+ }
240
+
241
+ // Step Prepare payload for Integration Service
193
242
  const mailPayload = {
194
243
  to: entity.to,
195
244
  subject: entity.subject,
196
245
  html: entity.message,
197
246
  cc: entity?.cc,
198
247
  bcc: entity?.bcc,
199
- templateId: entity.templateId,
248
+ templateId: resolvedTemplateId, // updated with resolved ID
200
249
  message: entity.message,
201
250
  type: entity.type || 'EMAIL',
202
251
  levelId: effectiveLevelId,
@@ -213,7 +262,7 @@ export class WrapperService {
213
262
  `Final payload for sendGenericMessage: ${JSON.stringify(mailPayload)}`,
214
263
  );
215
264
 
216
- // Step 4: Send mail via integration service
265
+ // Step 5️⃣ Send via Integration Service
217
266
  const result =
218
267
  await this.integrationService.sendGenericMessage(mailPayload);
219
268
 
@@ -1,4 +1,4 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { Injectable, Logger } from '@nestjs/common';
2
2
  import { BaseEntity } from 'src/module/meta/entity/base-entity.entity';
3
3
  import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service';
4
4
  import { UserData } from 'src/module/user/entity/user.entity';
@@ -7,6 +7,8 @@ import { DataSource } from 'typeorm';
7
7
 
8
8
  @Injectable()
9
9
  export class LayoutPreferenceService extends EntityServiceImpl {
10
+ private readonly logger = new Logger(LayoutPreferenceService.name);
11
+
10
12
  constructor(
11
13
  private layoutPreferenceRepository: LayoutPreferenceRepository,
12
14
  private readonly dataSource: DataSource,
@@ -79,62 +81,92 @@ export class LayoutPreferenceService extends EntityServiceImpl {
79
81
  sort_by: string,
80
82
  loggedInUser: UserData,
81
83
  ): Promise<string[]> {
82
- const getTableMeta =
83
- await this.entityTableService.findByEntityTypeAndListTypeAndDisplayType(
84
- entity_type,
85
- entity_type,
86
- 'LIST',
87
- loggedInUser?.organization_id,
84
+ try {
85
+ const getTableMeta =
86
+ await this.entityTableService.findByEntityTypeAndListTypeAndDisplayType(
87
+ entity_type,
88
+ entity_type,
89
+ 'LIST',
90
+ loggedInUser?.organization_id,
91
+ );
92
+
93
+ const tableName = getTableMeta?.data_source;
94
+
95
+ if (!tableName) {
96
+ throw new Error('Invalid or missing table name in metadata');
97
+ }
98
+
99
+ // Query DB to get distinct column values and counts
100
+ const rawData: { column_value: string; count: number }[] =
101
+ await this.dataSource
102
+ .createQueryBuilder()
103
+ .select(`${column} AS column_value`)
104
+ .addSelect(`COUNT(*) AS count`)
105
+ .from(tableName, tableName)
106
+ .where(`${column} IS NOT NULL`)
107
+ .andWhere(`organization_id = :organizationId`, {
108
+ organizationId: loggedInUser?.organization_id,
109
+ })
110
+ .andWhere(`level_id = :levelId`, { levelId: loggedInUser?.level_id })
111
+ .andWhere(`level_type = :levelType`, {
112
+ levelType: loggedInUser?.level_type,
113
+ })
114
+ .groupBy(column)
115
+ .getRawMany();
116
+
117
+ if (!rawData.length) {
118
+ return [];
119
+ }
120
+
121
+ // Prepare payload for resolver
122
+ const payloadBeforeResolved = rawData.map((row) => ({
123
+ [column]: row?.column_value,
124
+ }));
125
+
126
+ // Resolve column values using resolverService
127
+ const resolvedEntityList = await Promise.all(
128
+ payloadBeforeResolved.map((row) =>
129
+ this.resolverService.getResolvedData(loggedInUser, row, entity_type),
130
+ ),
88
131
  );
89
132
 
90
- const tableName = getTableMeta?.data_source;
91
-
92
- if (!tableName) {
93
- throw new Error('Invalid or missing table name in metadata');
133
+ // Merge resolved names with counts
134
+ const resolvedWithCounts = rawData.map((row, index) => {
135
+ const resolvedValue =
136
+ resolvedEntityList[index]?.[column] || row.column_value;
137
+ return {
138
+ resolvedValue,
139
+ count: Number(row.count),
140
+ };
141
+ });
142
+
143
+ // Sort based on sort_by parameter
144
+ switch (sort_by) {
145
+ case 'asc':
146
+ resolvedWithCounts.sort((a, b) =>
147
+ a.resolvedValue.localeCompare(b.resolvedValue),
148
+ );
149
+ break;
150
+ case 'dsc':
151
+ resolvedWithCounts.sort((a, b) =>
152
+ b.resolvedValue.localeCompare(a.resolvedValue),
153
+ );
154
+ break;
155
+ case 'count_asc':
156
+ resolvedWithCounts.sort((a, b) => a.count - b.count);
157
+ break;
158
+ case 'count_dsc':
159
+ resolvedWithCounts.sort((a, b) => b.count - a.count);
160
+ break;
161
+ default:
162
+ break;
163
+ }
164
+
165
+ // Return only the resolved value list
166
+ return resolvedWithCounts.map((item) => item.resolvedValue);
167
+ } catch (error) {
168
+ this.logger.error(`getColumnValue ERROR: ${error.message}`, error.stack);
169
+ return [];
94
170
  }
95
-
96
- // Query to get counts of distinct values in the column
97
- const rawData: { column_value: string; count: number }[] =
98
- await this.dataSource
99
- .createQueryBuilder()
100
- .select(`${column} AS column_value`)
101
- .addSelect(`COUNT(*) AS count`)
102
- .from(tableName, tableName)
103
- .where(`${column} IS NOT NULL`)
104
- .andWhere(`organization_id = :organizationId`, {
105
- organizationId: loggedInUser?.organization_id,
106
- })
107
- .andWhere(`level_id = :levelId`, { levelId: loggedInUser?.level_id })
108
- .andWhere(`level_type = :levelType`, {
109
- levelType: loggedInUser?.level_type,
110
- })
111
- .groupBy(column)
112
- .getRawMany();
113
-
114
- // Convert result to map and sort
115
- const result = Object.fromEntries(
116
- rawData.map((row) => [row.column_value, Number(row.count)]),
117
- );
118
-
119
- const entries = Object.entries(result);
120
-
121
- switch (sort_by) {
122
- case 'asc':
123
- entries.sort(([a], [b]) => a.localeCompare(b));
124
- break;
125
- case 'dsc':
126
- entries.sort(([a], [b]) => b.localeCompare(a));
127
- break;
128
- case 'count_asc':
129
- entries.sort(([, countA], [, countB]) => countA - countB);
130
- break;
131
- case 'count_dsc':
132
- entries.sort(([, countA], [, countB]) => countB - countA);
133
- break;
134
- default:
135
- break;
136
- }
137
-
138
- return entries.map(([value]) => value);
139
171
  }
140
172
  }