rez_core 1.0.77 → 1.0.79
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/dist/module/meta/controller/entity.controller.d.ts +2 -2
- package/dist/module/meta/controller/entity.controller.js +11 -8
- package/dist/module/meta/controller/entity.controller.js.map +1 -1
- package/dist/module/meta/entity.module.js +3 -0
- package/dist/module/meta/entity.module.js.map +1 -1
- package/dist/module/meta/service/entity-list.service.d.ts +1 -1
- package/dist/module/meta/service/entity-list.service.js +4 -1
- package/dist/module/meta/service/entity-list.service.js.map +1 -1
- package/dist/module/meta/service/entity-service-impl.service.d.ts +2 -2
- package/dist/module/meta/service/entity-service-impl.service.js +11 -8
- package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
- package/dist/module/meta/service/entity-validation.service.d.ts +17 -0
- package/dist/module/meta/service/entity-validation.service.js +76 -0
- package/dist/module/meta/service/entity-validation.service.js.map +1 -0
- package/dist/module/meta/service/entity.service.d.ts +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/meta/controller/entity.controller.ts +7 -0
- package/src/module/meta/entity.module.ts +3 -0
- package/src/module/meta/service/entity-list.service.ts +6 -0
- package/src/module/meta/service/entity-service-impl.service.ts +24 -14
- package/src/module/meta/service/entity-validation.service.ts +95 -0
- package/src/module/meta/service/entity.service.ts +1 -0
package/package.json
CHANGED
|
@@ -132,6 +132,8 @@ export class EntityController {
|
|
|
132
132
|
@Query('sort_order') sortOrder?: string,
|
|
133
133
|
@Query('page') page: number = 0,
|
|
134
134
|
@Query('size') size: number = 1,
|
|
135
|
+
@Query('tab_column') tabColumn?: string,
|
|
136
|
+
@Query('tab_value') tabValue?: string,
|
|
135
137
|
) {
|
|
136
138
|
return res
|
|
137
139
|
.status(HttpStatus.OK)
|
|
@@ -144,6 +146,8 @@ export class EntityController {
|
|
|
144
146
|
sortOrder,
|
|
145
147
|
page,
|
|
146
148
|
size,
|
|
149
|
+
tabColumn,
|
|
150
|
+
tabValue
|
|
147
151
|
),
|
|
148
152
|
);
|
|
149
153
|
}
|
|
@@ -155,15 +159,18 @@ export class EntityController {
|
|
|
155
159
|
@Param('entity_type') entityType: string,
|
|
156
160
|
@Query('list_entity_type') listEntityType: string,
|
|
157
161
|
@Query('display_type') displayType: string,
|
|
162
|
+
@Query('sample_export') sampleExport: boolean,
|
|
158
163
|
@Query() filterCriteria: Record<string, any>,
|
|
159
164
|
@Res() res: Response, // Express Response for file handling
|
|
160
165
|
) {
|
|
161
166
|
try {
|
|
167
|
+
|
|
162
168
|
const filePath = await this.entityService.generateExcelReport(
|
|
163
169
|
entityType,
|
|
164
170
|
filterCriteria,
|
|
165
171
|
listEntityType,
|
|
166
172
|
displayType,
|
|
173
|
+
sampleExport
|
|
167
174
|
);
|
|
168
175
|
|
|
169
176
|
if (!filePath || !fs.existsSync(filePath)) {
|
|
@@ -35,6 +35,7 @@ import { ViewMasterService } from './service/view-master.service';
|
|
|
35
35
|
import { ViewMasterController } from './controller/view-master.controller';
|
|
36
36
|
import { ViewMaterRespository } from './repository/view-master.repository';
|
|
37
37
|
import { MetaController } from './controller/meta.controller';
|
|
38
|
+
import { EntityValidationService } from './service/entity-validation.service';
|
|
38
39
|
|
|
39
40
|
@Module({
|
|
40
41
|
imports: [
|
|
@@ -71,6 +72,7 @@ import { MetaController } from './controller/meta.controller';
|
|
|
71
72
|
SectionMasterService,
|
|
72
73
|
FieldGroupService,
|
|
73
74
|
ViewMaterRespository,
|
|
75
|
+
EntityValidationService,
|
|
74
76
|
{ provide: 'ViewMasterService', useClass: ViewMasterService },
|
|
75
77
|
],
|
|
76
78
|
exports: [
|
|
@@ -79,6 +81,7 @@ import { MetaController } from './controller/meta.controller';
|
|
|
79
81
|
PreferenceService,
|
|
80
82
|
EntityListService,
|
|
81
83
|
EntityTableService,
|
|
84
|
+
EntityValidationService,
|
|
82
85
|
EntityTableColumnService,
|
|
83
86
|
MediaDataService,
|
|
84
87
|
SectionMasterService,
|
|
@@ -23,6 +23,8 @@ export class EntityListService {
|
|
|
23
23
|
sortOrder: string | undefined,
|
|
24
24
|
pageNumber: number,
|
|
25
25
|
pageSize: number,
|
|
26
|
+
tabColumn?: string,
|
|
27
|
+
tabValue?: string,
|
|
26
28
|
): Promise<EntityListData> {
|
|
27
29
|
let entityListData = new EntityListData();
|
|
28
30
|
|
|
@@ -35,6 +37,10 @@ export class EntityListService {
|
|
|
35
37
|
if (1 != entityTable.is_proc) {
|
|
36
38
|
let totalCount = await this.getTotalCount(entityTable, filters);
|
|
37
39
|
entityListData.entity_tabs = totalCount as EntityTab[];
|
|
40
|
+
|
|
41
|
+
if (tabColumn && tabValue) {
|
|
42
|
+
filters[tabColumn] = tabValue;
|
|
43
|
+
}
|
|
38
44
|
entityListData.entity_list = await this.getFilteredList(
|
|
39
45
|
entityTable,
|
|
40
46
|
filters,
|
|
@@ -165,6 +165,8 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
|
|
|
165
165
|
sortOrder: string | undefined,
|
|
166
166
|
pageNumber: number,
|
|
167
167
|
pageSize: number,
|
|
168
|
+
tabColumn?: string,
|
|
169
|
+
tabValue?: string,
|
|
168
170
|
): Promise<EntityListData> {
|
|
169
171
|
return await this.entityListService.getFilterDataWithTabs(
|
|
170
172
|
entityType,
|
|
@@ -174,6 +176,8 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
|
|
|
174
176
|
sortOrder,
|
|
175
177
|
pageNumber,
|
|
176
178
|
pageSize,
|
|
179
|
+
tabColumn,
|
|
180
|
+
tabValue
|
|
177
181
|
);
|
|
178
182
|
}
|
|
179
183
|
|
|
@@ -182,6 +186,7 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
|
|
|
182
186
|
filterCriteria: Record<string, any>,
|
|
183
187
|
listEntityType: string,
|
|
184
188
|
displayType: string,
|
|
189
|
+
sampleExport: boolean,
|
|
185
190
|
): Promise<string | null> {
|
|
186
191
|
let fileName: string;
|
|
187
192
|
try {
|
|
@@ -192,6 +197,7 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
|
|
|
192
197
|
filterCriteria,
|
|
193
198
|
listEntityType,
|
|
194
199
|
displayType,
|
|
200
|
+
sampleExport
|
|
195
201
|
);
|
|
196
202
|
|
|
197
203
|
const modifiedDate = new Date().toISOString().replace(/[-T:.Z]/g, '');
|
|
@@ -214,19 +220,20 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
|
|
|
214
220
|
filterCriteria: Record<string, any>,
|
|
215
221
|
listEntityType: string,
|
|
216
222
|
displayType: string,
|
|
223
|
+
sampleExport: boolean,
|
|
217
224
|
) {
|
|
218
|
-
const sheet: ExcelsheetData = {
|
|
219
|
-
sheetName: entityType,
|
|
220
|
-
headers: [],
|
|
221
|
-
rowList: [],
|
|
222
|
-
};
|
|
223
|
-
|
|
224
225
|
const entityTable =
|
|
225
226
|
await this.entityTableService.findByEntityTypeAndListTypeAndDisplayType(
|
|
226
227
|
entityType,
|
|
227
228
|
listEntityType,
|
|
228
229
|
displayType,
|
|
229
230
|
);
|
|
231
|
+
const sheet: ExcelsheetData = {
|
|
232
|
+
sheetName: entityTable?.data_source || 'sheet',
|
|
233
|
+
headers: [],
|
|
234
|
+
rowList: [],
|
|
235
|
+
};
|
|
236
|
+
|
|
230
237
|
if (entityTable) {
|
|
231
238
|
const entityTableColumnList =
|
|
232
239
|
await this.entityTableColumnService.findByParentIdAndParentType(
|
|
@@ -239,14 +246,17 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
|
|
|
239
246
|
(col) => col.attribute_key,
|
|
240
247
|
);
|
|
241
248
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
249
|
+
let filteredList: any[] = [];
|
|
250
|
+
if(!sampleExport) {
|
|
251
|
+
filteredList = await this.entityListService.getFilteredList(
|
|
252
|
+
entityTable,
|
|
253
|
+
filterCriteria,
|
|
254
|
+
undefined,
|
|
255
|
+
undefined,
|
|
256
|
+
undefined,
|
|
257
|
+
undefined,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
250
260
|
|
|
251
261
|
sheet.rowList = filteredList.map((item) =>
|
|
252
262
|
attributeList.map((attr) =>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { AttributeMasterService } from 'src/module/meta/service/attribute-master.service';
|
|
3
|
+
import { AttributeMaster } from '../entity/attribute-master.entity';
|
|
4
|
+
import { ReflectionHelper } from 'src/utils/service/reflection-helper.service';
|
|
5
|
+
|
|
6
|
+
interface ValidationError {
|
|
7
|
+
field: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@Injectable()
|
|
12
|
+
export class EntityValidationService {
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly attributeMasterService: AttributeMasterService,
|
|
15
|
+
private readonly reflectionHelper: ReflectionHelper
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Validates required fields based on attribute metadata.
|
|
20
|
+
*/
|
|
21
|
+
validateRequiredFields(
|
|
22
|
+
entityData: Record<string, any>,
|
|
23
|
+
attributeData: AttributeMaster[],
|
|
24
|
+
): ValidationError[] {
|
|
25
|
+
const errors: ValidationError[] = [];
|
|
26
|
+
|
|
27
|
+
attributeData
|
|
28
|
+
.filter(attr => attr.required)
|
|
29
|
+
.forEach(attr => {
|
|
30
|
+
const value = entityData[attr.code];
|
|
31
|
+
if (!this.hasValidValue(value)) {
|
|
32
|
+
errors.push({
|
|
33
|
+
field: attr.code,
|
|
34
|
+
message: `Field "${attr.code}" is required.`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return errors;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Validates uniqueness of fields based on attribute metadata.
|
|
44
|
+
*/
|
|
45
|
+
async validateUniqueFields(
|
|
46
|
+
entityData: Record<string, any>,
|
|
47
|
+
attributeData: AttributeMaster[],
|
|
48
|
+
entityType: string
|
|
49
|
+
): Promise<ValidationError[]> {
|
|
50
|
+
const errors: ValidationError[] = [];
|
|
51
|
+
|
|
52
|
+
const repo = this.reflectionHelper.getRepoService(entityData.entity_type);
|
|
53
|
+
|
|
54
|
+
if (!repo) {
|
|
55
|
+
throw new Error(`Repository service not found for entityType: ${entityType}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const attr of attributeData.filter(a => a.is_unique)) {
|
|
59
|
+
const value = entityData[attr.code];
|
|
60
|
+
if (this.hasValidValue(value)) {
|
|
61
|
+
const existing = await repo.findOne({ where: { [attr.code]: value } });
|
|
62
|
+
if (existing) {
|
|
63
|
+
errors.push({
|
|
64
|
+
field: attr.code,
|
|
65
|
+
message: `Field "${attr.code}" must be unique. Value "${value}" already exists.`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return errors;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Validates both required and unique fields for a given entity type.
|
|
77
|
+
*/
|
|
78
|
+
async validateEntityData(
|
|
79
|
+
entityData: Record<string, any>
|
|
80
|
+
): Promise<ValidationError[]> {
|
|
81
|
+
const attributes = await this.attributeMasterService.findAttributesByMappedEntityType(entityData.entity_type);
|
|
82
|
+
|
|
83
|
+
const requiredErrors = this.validateRequiredFields(entityData, attributes);
|
|
84
|
+
const uniqueErrors = await this.validateUniqueFields(entityData, attributes, entityData.entity_type);
|
|
85
|
+
|
|
86
|
+
return [...requiredErrors, ...uniqueErrors];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
private hasValidValue(value: any): boolean {
|
|
91
|
+
if (value === null || value === undefined) return false;
|
|
92
|
+
if (typeof value === 'string' && value.trim() === '') return false;
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|