rez_core 4.0.246 → 4.0.291
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/entity_json/entity_json.module.js +1 -2
- package/dist/module/entity_json/entity_json.module.js.map +1 -1
- package/dist/module/entity_json/service/entity_json.service.d.ts +1 -3
- package/dist/module/entity_json/service/entity_json.service.js +73 -48
- package/dist/module/entity_json/service/entity_json.service.js.map +1 -1
- package/dist/module/filter/service/filter.service.js +84 -14
- package/dist/module/filter/service/filter.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/entity_json/entity_json.module.ts +1 -2
- package/src/module/entity_json/service/entity_json.service.ts +165 -81
- package/src/module/filter/service/filter.service.ts +109 -16
- package/dist/module/entity_json/service/entityJson.repository.d.ts +0 -7
- package/dist/module/entity_json/service/entityJson.repository.js +0 -45
- package/dist/module/entity_json/service/entityJson.repository.js.map +0 -1
- package/src/module/entity_json/service/entityJson.repository.ts +0 -37
package/package.json
CHANGED
|
@@ -6,12 +6,11 @@ import { EntityJSONController } from './controller/entity_json.controller';
|
|
|
6
6
|
import { FilterModule } from '../filter/filter.module';
|
|
7
7
|
import { UtilsModule } from 'src/utils/utils.module';
|
|
8
8
|
import { EntityJson } from './entity/entityJson.entity';
|
|
9
|
-
import { EntityJSONRepository } from './service/entityJson.repository';
|
|
10
9
|
|
|
11
10
|
@Module({
|
|
12
11
|
imports: [EntityModule, TypeOrmModule.forFeature([EntityJson]),FilterModule,UtilsModule],
|
|
13
12
|
controllers: [EntityJSONController],
|
|
14
|
-
providers: [EntityJSONService
|
|
13
|
+
providers: [EntityJSONService],
|
|
15
14
|
exports: [],
|
|
16
15
|
})
|
|
17
16
|
export class EntityJSONModule {}
|
|
@@ -6,15 +6,13 @@ import { EntityRelation } from 'src/module/meta/entity/entity-relation.entity';
|
|
|
6
6
|
import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service';
|
|
7
7
|
import { LoggingService } from 'src/utils/service/loggingUtil.service';
|
|
8
8
|
import { DataSource } from 'typeorm';
|
|
9
|
-
import { EntityJSONRepository } from './entityJson.repository';
|
|
10
9
|
|
|
11
10
|
@Injectable()
|
|
12
11
|
export class EntityJSONService extends EntityServiceImpl {
|
|
13
12
|
constructor(
|
|
14
13
|
private readonly dataSource: DataSource,
|
|
15
14
|
private readonly filterService: FilterService,
|
|
16
|
-
private readonly loggerService: LoggingService,
|
|
17
|
-
private readonly EntityJSONRepository:EntityJSONRepository
|
|
15
|
+
private readonly loggerService: LoggingService, // <-- inject logging service
|
|
18
16
|
) {
|
|
19
17
|
super();
|
|
20
18
|
}
|
|
@@ -25,18 +23,27 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
25
23
|
flag?: 'flat_json' | 'dropdown' | 'all',
|
|
26
24
|
) {
|
|
27
25
|
const orgId = loggedInUser.organization_id;
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
await this.loggerService.log(
|
|
27
|
+
'info',
|
|
28
|
+
'EntityJSONService',
|
|
29
|
+
'getAttributeForFlatJSON',
|
|
30
|
+
`Loading attributes for entity: ${entityType}, org: ${orgId}`,
|
|
31
|
+
);
|
|
30
32
|
|
|
31
33
|
const mainAttributes = await this.dataSource
|
|
32
34
|
.getRepository(AttributeMaster)
|
|
33
35
|
.createQueryBuilder('attr')
|
|
34
|
-
.select(['attr.id', 'attr.name', 'attr.flat_json_key',
|
|
36
|
+
.select(['attr.id', 'attr.name', 'attr.flat_json_key','attr.attribute_key'])
|
|
35
37
|
.where('attr.mapped_entity_type = :entityType', { entityType })
|
|
36
38
|
.andWhere('attr.organization_id = :orgId', { orgId })
|
|
37
39
|
.getMany();
|
|
38
40
|
|
|
39
|
-
await this.loggerService.log(
|
|
41
|
+
await this.loggerService.log(
|
|
42
|
+
'debug',
|
|
43
|
+
'EntityJSONService',
|
|
44
|
+
'getAttributeForFlatJSON',
|
|
45
|
+
`Loaded ${mainAttributes.length} main attributes`,
|
|
46
|
+
);
|
|
40
47
|
|
|
41
48
|
const relatedEntityTypes = await this.dataSource
|
|
42
49
|
.getRepository(EntityRelation)
|
|
@@ -44,24 +51,44 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
44
51
|
.select(['rel.target_entity_type'])
|
|
45
52
|
.where('rel.source_entity_type = :entityType', { entityType })
|
|
46
53
|
.andWhere('rel.organization_id = :orgId', { orgId })
|
|
47
|
-
.andWhere('rel.relation_type = :relationType', {
|
|
54
|
+
.andWhere('rel.relation_type = :relationType', {
|
|
55
|
+
relationType: 'ONE_TO_ONE',
|
|
56
|
+
})
|
|
48
57
|
.getRawMany();
|
|
49
58
|
|
|
50
|
-
const relatedTypesList = relatedEntityTypes.map(
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
const relatedTypesList = relatedEntityTypes.map(
|
|
60
|
+
(x) => x.rel_target_entity_type,
|
|
61
|
+
);
|
|
62
|
+
await this.loggerService.log(
|
|
63
|
+
'debug',
|
|
64
|
+
'EntityJSONService',
|
|
65
|
+
'getAttributeForFlatJSON',
|
|
66
|
+
`Found ${relatedTypesList.length} ONE-TO-ONE related entity types`,
|
|
67
|
+
);
|
|
53
68
|
|
|
54
69
|
const relatedAttributes = relatedTypesList.length
|
|
55
70
|
? await this.dataSource
|
|
56
71
|
.getRepository(AttributeMaster)
|
|
57
72
|
.createQueryBuilder('attr')
|
|
58
|
-
.select([
|
|
59
|
-
|
|
73
|
+
.select([
|
|
74
|
+
'attr.id',
|
|
75
|
+
'attr.name',
|
|
76
|
+
'attr.flat_json_key',
|
|
77
|
+
'attr.mapped_entity_type',
|
|
78
|
+
'attr.attribute_key',
|
|
79
|
+
])
|
|
80
|
+
.where('attr.mapped_entity_type IN (:...types)', {
|
|
81
|
+
types: relatedTypesList,
|
|
82
|
+
})
|
|
60
83
|
.andWhere('attr.organization_id = :orgId', { orgId })
|
|
61
84
|
.getMany()
|
|
62
85
|
: [];
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
await this.loggerService.log(
|
|
87
|
+
'debug',
|
|
88
|
+
'EntityJSONService',
|
|
89
|
+
'getAttributeForFlatJSON',
|
|
90
|
+
`Loaded ${relatedAttributes.length} related attributes`,
|
|
91
|
+
);
|
|
65
92
|
|
|
66
93
|
const linkedAttributes = await this.dataSource
|
|
67
94
|
.getRepository(LinkedAttributes)
|
|
@@ -72,67 +99,103 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
72
99
|
'fla.applicable_entity_type = attr.mapped_entity_type AND fla.applicable_attribute_key = attr.attribute_key',
|
|
73
100
|
)
|
|
74
101
|
.select([
|
|
75
|
-
'fla.applicable_entity_type
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'attr.name AS name',
|
|
80
|
-
'attr.id AS id',
|
|
102
|
+
'fla.applicable_entity_type',
|
|
103
|
+
'attr.id',
|
|
104
|
+
'attr.name',
|
|
105
|
+
'attr.attribute_key',
|
|
81
106
|
])
|
|
82
107
|
.where('attr.organization_id = :orgId', { orgId })
|
|
83
108
|
.getRawMany();
|
|
84
|
-
|
|
85
|
-
|
|
109
|
+
await this.loggerService.log(
|
|
110
|
+
'debug',
|
|
111
|
+
'EntityJSONService',
|
|
112
|
+
'getAttributeForFlatJSON',
|
|
113
|
+
`Loaded ${linkedAttributes.length} linked attributes`,
|
|
114
|
+
);
|
|
86
115
|
|
|
87
116
|
if (flag === 'flat_json' || flag === 'all') {
|
|
88
117
|
const result: Record<string, null> = {};
|
|
89
|
-
mainAttributes.forEach(attr => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
mainAttributes.forEach((attr) => {
|
|
119
|
+
if (attr.flat_json_key) result[attr.flat_json_key] = null;
|
|
120
|
+
});
|
|
121
|
+
relatedAttributes.forEach((attr) => {
|
|
122
|
+
if (attr.flat_json_key) result[attr.flat_json_key] = null;
|
|
123
|
+
});
|
|
124
|
+
linkedAttributes.forEach((link) => {
|
|
125
|
+
if (link.applicable_attribute_key)
|
|
126
|
+
result[link.applicable_attribute_key] = null;
|
|
127
|
+
});
|
|
128
|
+
if(flag === 'all')
|
|
129
|
+
return {flat_json: result,attributes: {mainAttributes,relatedAttributes,linkedAttributes}};
|
|
130
|
+
|
|
131
|
+
return result;
|
|
98
132
|
}
|
|
99
133
|
|
|
100
134
|
const dropdown: any[] = [];
|
|
101
|
-
dropdown.push(
|
|
102
|
-
|
|
135
|
+
dropdown.push(
|
|
136
|
+
...mainAttributes.map((a) => ({ label: a.name, value: a.flat_json_key })),
|
|
137
|
+
);
|
|
138
|
+
dropdown.push(
|
|
139
|
+
...relatedAttributes.map((a) => ({
|
|
140
|
+
label: a.name,
|
|
141
|
+
value: a.flat_json_key,
|
|
142
|
+
})),
|
|
143
|
+
);
|
|
103
144
|
if (linkedAttributes.length > 0) {
|
|
104
|
-
dropdown.push(
|
|
145
|
+
dropdown.push({
|
|
146
|
+
...linkedAttributes.map((a) => ({
|
|
147
|
+
label: a.name,
|
|
148
|
+
value: a.attribute_key,
|
|
149
|
+
})),
|
|
150
|
+
});
|
|
105
151
|
}
|
|
106
|
-
|
|
107
152
|
return dropdown;
|
|
108
153
|
}
|
|
109
154
|
|
|
110
155
|
async updateEntityJSON(entityType: string, entityId: number, loggedInUser) {
|
|
111
|
-
await this.loggerService.log(
|
|
112
|
-
|
|
156
|
+
await this.loggerService.log(
|
|
157
|
+
'info',
|
|
158
|
+
'EntityJSONService',
|
|
159
|
+
'updateEntityJSON',
|
|
160
|
+
`Building flat JSON for entity: ${entityType}#${entityId}`,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// 1. Load flat JSON template + attributes
|
|
113
164
|
const response = await this.getAttributeForFlatJSON(entityType, loggedInUser, 'all');
|
|
114
|
-
|
|
165
|
+
|
|
166
|
+
// ---- Structural validation ----
|
|
115
167
|
if (!response || !('flat_json' in response) || !('attributes' in response) || !response.attributes) {
|
|
116
|
-
await this.loggerService.log(
|
|
168
|
+
await this.loggerService.log(
|
|
169
|
+
'error',
|
|
170
|
+
'EntityJSONService',
|
|
171
|
+
'updateEntityJSON',
|
|
172
|
+
`getAttributeForFlatJSON() did not return expected structure`,
|
|
173
|
+
);
|
|
117
174
|
return null;
|
|
118
175
|
}
|
|
119
|
-
|
|
176
|
+
|
|
120
177
|
const { flat_json: flatJson, attributes } = response;
|
|
121
178
|
if (!flatJson) return null;
|
|
122
|
-
|
|
179
|
+
|
|
180
|
+
// ---- Strong safety fix ----
|
|
123
181
|
const safeAttributes = {
|
|
124
182
|
mainAttributes: attributes.mainAttributes || [],
|
|
125
183
|
relatedAttributes: attributes.relatedAttributes || [],
|
|
126
184
|
linkedAttributes: attributes.linkedAttributes || [],
|
|
127
185
|
};
|
|
128
|
-
|
|
186
|
+
|
|
187
|
+
// 2. Build attribute_key → flat_json_key map
|
|
129
188
|
const attrMap: Record<string, string> = {};
|
|
130
189
|
const allAttrs = [...safeAttributes.mainAttributes, ...safeAttributes.relatedAttributes];
|
|
131
|
-
allAttrs.forEach(attr => {
|
|
132
|
-
|
|
190
|
+
allAttrs.forEach(attr => {
|
|
191
|
+
if (attr.attribute_key) attrMap[attr.attribute_key] = attr.flat_json_key || attr.attribute_key;
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// 3. Merge main entity data
|
|
133
195
|
const mainData = await this.getResolvedEntityData(entityType, entityId, loggedInUser);
|
|
134
196
|
this.mergeEntityDataIntoFlatJson(flatJson, mainData, attrMap);
|
|
135
|
-
|
|
197
|
+
|
|
198
|
+
// 4. Merge ONE-TO-ONE related entities
|
|
136
199
|
const relations = await this.dataSource
|
|
137
200
|
.getRepository('frm_entity_relation_data')
|
|
138
201
|
.createQueryBuilder('erd')
|
|
@@ -141,62 +204,67 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
141
204
|
.andWhere('erd.source_entity_id = :entityId', { entityId })
|
|
142
205
|
.andWhere('erd.relation_type = :rt', { rt: 'ONE_TO_ONE' })
|
|
143
206
|
.getRawMany();
|
|
144
|
-
|
|
207
|
+
|
|
145
208
|
for (const rel of relations) {
|
|
146
209
|
const relatedData = await this.getResolvedEntityData(rel.target_entity_type, rel.target_entity_id, loggedInUser);
|
|
147
210
|
this.mergeEntityDataIntoFlatJson(flatJson, relatedData, attrMap);
|
|
148
211
|
}
|
|
149
|
-
|
|
212
|
+
|
|
213
|
+
// 5. Merge linked attributes using saved filters
|
|
150
214
|
for (const linkAttr of safeAttributes.linkedAttributes) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
if (!childEntityType || !sourceKey || !targetKey) continue;
|
|
156
|
-
|
|
157
|
-
const mappingValue = mainData?.[sourceKey] ?? null;
|
|
158
|
-
|
|
215
|
+
if (!linkAttr.applicable_entity_type || !linkAttr.applicable_attribute_key) continue;
|
|
216
|
+
|
|
217
|
+
const mappingValue = mainData?.[linkAttr.parent_attribute_key || ''] ?? null;
|
|
159
218
|
const value = await this.applyLinkedFilterUsingSavedFilter(
|
|
160
|
-
|
|
219
|
+
linkAttr.applicable_entity_type,
|
|
161
220
|
linkAttr.saved_filter_code,
|
|
162
|
-
|
|
221
|
+
linkAttr.applicable_attribute_key,
|
|
163
222
|
mappingValue,
|
|
164
|
-
|
|
223
|
+
linkAttr.target_attribute_key || linkAttr.applicable_attribute_key,
|
|
165
224
|
loggedInUser,
|
|
166
225
|
entityId,
|
|
167
226
|
);
|
|
168
|
-
|
|
227
|
+
|
|
169
228
|
if (value !== null && value !== undefined) {
|
|
170
|
-
|
|
229
|
+
const flatKey = attrMap[linkAttr.target_attribute_key || linkAttr.applicable_attribute_key]
|
|
230
|
+
|| (linkAttr.target_attribute_key || linkAttr.applicable_attribute_key);
|
|
231
|
+
flatJson[flatKey] = value;
|
|
171
232
|
}
|
|
172
233
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
entity_type
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
await this.EntityJSONRepository.create(JsonData);
|
|
183
|
-
|
|
234
|
+
|
|
235
|
+
// 6. Save JSON
|
|
236
|
+
await this.dataSource.query(
|
|
237
|
+
`INSERT INTO frm_entity_json (entity_type, entity_id, json_data, created_by)
|
|
238
|
+
VALUES (?, ?, ?, ?)
|
|
239
|
+
ON DUPLICATE KEY UPDATE json_data = VALUES(json_data), updated_by = VALUES(created_by)`,
|
|
240
|
+
[entityType, entityId, JSON.stringify(flatJson), loggedInUser.id],
|
|
241
|
+
);
|
|
242
|
+
|
|
184
243
|
return flatJson;
|
|
185
244
|
}
|
|
186
|
-
|
|
187
|
-
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
// Helper: Merge entity data using attribute_key → flat_json_key mapping
|
|
248
|
+
private mergeEntityDataIntoFlatJson(
|
|
249
|
+
flatJson: Record<string, any>,
|
|
250
|
+
entityData: any | any[], // accept both object or array
|
|
251
|
+
attrMap: Record<string, string>,
|
|
252
|
+
) {
|
|
188
253
|
const records = Array.isArray(entityData) ? entityData : [entityData];
|
|
189
|
-
|
|
254
|
+
|
|
190
255
|
for (const record of records) {
|
|
191
256
|
if (!record || typeof record !== 'object') continue;
|
|
257
|
+
|
|
192
258
|
for (const key of Object.keys(record)) {
|
|
193
|
-
const flatKey = attrMap[key] || key;
|
|
259
|
+
const flatKey = attrMap[key] || key; // map to flat_json_key if exists
|
|
194
260
|
if (flatJson.hasOwnProperty(flatKey)) {
|
|
195
261
|
flatJson[flatKey] = record[key];
|
|
196
262
|
}
|
|
197
263
|
}
|
|
198
264
|
}
|
|
199
265
|
}
|
|
266
|
+
|
|
267
|
+
|
|
200
268
|
|
|
201
269
|
private async applyLinkedFilterUsingSavedFilter(
|
|
202
270
|
childEntityType: string,
|
|
@@ -207,7 +275,11 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
207
275
|
loggedInUser,
|
|
208
276
|
entity_id
|
|
209
277
|
) {
|
|
210
|
-
if (
|
|
278
|
+
if (
|
|
279
|
+
!savedFilterCode &&
|
|
280
|
+
(mappingValue === null || mappingValue === undefined)
|
|
281
|
+
)
|
|
282
|
+
return null;
|
|
211
283
|
|
|
212
284
|
const dto: any = {
|
|
213
285
|
entity_type: childEntityType,
|
|
@@ -217,18 +289,30 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
217
289
|
size: 1,
|
|
218
290
|
};
|
|
219
291
|
|
|
220
|
-
if (
|
|
292
|
+
if (
|
|
293
|
+
mappingValue !== null &&
|
|
294
|
+
mappingValue !== undefined &&
|
|
295
|
+
mappingValue !== ''
|
|
296
|
+
) {
|
|
221
297
|
dto.quickFilter = [
|
|
222
|
-
{
|
|
298
|
+
{
|
|
299
|
+
filter_attribute: childFilterAttribute,
|
|
300
|
+
filter_operator: 'equal',
|
|
301
|
+
filter_value: mappingValue,
|
|
302
|
+
},
|
|
223
303
|
];
|
|
224
304
|
}
|
|
225
305
|
|
|
226
306
|
dto.quickFilter = [
|
|
227
|
-
{
|
|
307
|
+
{
|
|
308
|
+
filter_attribute: 'parent_id',
|
|
309
|
+
filter_operator: 'equal',
|
|
310
|
+
filter_value: entity_id,
|
|
311
|
+
},
|
|
228
312
|
];
|
|
229
313
|
|
|
230
314
|
const result = await this.filterService.applyFilter(dto);
|
|
231
315
|
const rows = result?.data?.entity_list || [];
|
|
232
|
-
return rows.length ? (rows[0][
|
|
316
|
+
return rows.length ? (rows[0][targetAttribute] ?? null) : null;
|
|
233
317
|
}
|
|
234
318
|
}
|
|
@@ -848,13 +848,107 @@ export class FilterService {
|
|
|
848
848
|
}
|
|
849
849
|
|
|
850
850
|
private buildDateCondition(attr: string, op: string, val: any, key: string) {
|
|
851
|
+
const dateColumn = `DATE(e.${attr})`;
|
|
852
|
+
const monthColumn = `DATE_TRUNC('month', e.${attr})`;
|
|
853
|
+
|
|
854
|
+
const numVal = Number(val);
|
|
855
|
+
|
|
851
856
|
switch (op) {
|
|
857
|
+
// ===== BASIC COMPARISONS =====
|
|
852
858
|
case 'equal':
|
|
853
|
-
|
|
859
|
+
case 'is':
|
|
860
|
+
return {
|
|
861
|
+
query: `${dateColumn} = :${key}`,
|
|
862
|
+
params: { [key]: val },
|
|
863
|
+
};
|
|
864
|
+
|
|
854
865
|
case 'before':
|
|
855
|
-
|
|
866
|
+
case 'is_before':
|
|
867
|
+
return {
|
|
868
|
+
query: `${dateColumn} < :${key}`,
|
|
869
|
+
params: { [key]: val },
|
|
870
|
+
};
|
|
871
|
+
|
|
856
872
|
case 'after':
|
|
857
|
-
|
|
873
|
+
case 'is_after':
|
|
874
|
+
return {
|
|
875
|
+
query: `${dateColumn} > :${key}`,
|
|
876
|
+
params: { [key]: val },
|
|
877
|
+
};
|
|
878
|
+
|
|
879
|
+
case 'is_on_or_before':
|
|
880
|
+
return {
|
|
881
|
+
query: `${dateColumn} <= :${key}`,
|
|
882
|
+
params: { [key]: val },
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
case 'is_on_or_after':
|
|
886
|
+
return {
|
|
887
|
+
query: `${dateColumn} >= :${key}`,
|
|
888
|
+
params: { [key]: val },
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
// ===== MONTH COMPARISONS (NUMERIC OR DATE) =====
|
|
892
|
+
case 'is_month_before':
|
|
893
|
+
if (!isNaN(numVal)) {
|
|
894
|
+
const target = moment()
|
|
895
|
+
.subtract(numVal, 'months')
|
|
896
|
+
.startOf('month')
|
|
897
|
+
.format('YYYY-MM-DD');
|
|
898
|
+
return {
|
|
899
|
+
query: `${monthColumn} < DATE_TRUNC('month', :${key})`,
|
|
900
|
+
params: { [key]: target },
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
return {
|
|
904
|
+
query: `${monthColumn} < DATE_TRUNC('month', :${key})`,
|
|
905
|
+
params: { [key]: val },
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
case 'is_month_after':
|
|
909
|
+
if (!isNaN(numVal)) {
|
|
910
|
+
const target = moment()
|
|
911
|
+
.add(numVal, 'months')
|
|
912
|
+
.startOf('month')
|
|
913
|
+
.format('YYYY-MM-DD');
|
|
914
|
+
return {
|
|
915
|
+
query: `${monthColumn} > DATE_TRUNC('month', :${key})`,
|
|
916
|
+
params: { [key]: target },
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
return {
|
|
920
|
+
query: `${monthColumn} > DATE_TRUNC('month', :${key})`,
|
|
921
|
+
params: { [key]: val },
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
// ===== DAY BEFORE / AFTER WITH MOMENT =====
|
|
925
|
+
case 'is_day_before':
|
|
926
|
+
if (isNaN(numVal))
|
|
927
|
+
throw new BadRequestException(
|
|
928
|
+
'Value must be a number for is_day_before',
|
|
929
|
+
);
|
|
930
|
+
|
|
931
|
+
return {
|
|
932
|
+
query: `${dateColumn} < :${key}`,
|
|
933
|
+
params: {
|
|
934
|
+
[key]: moment().subtract(numVal, 'days').format('YYYY-MM-DD'),
|
|
935
|
+
},
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
case 'is_day_after':
|
|
939
|
+
if (isNaN(numVal))
|
|
940
|
+
throw new BadRequestException(
|
|
941
|
+
'Value must be a number for is_day_after',
|
|
942
|
+
);
|
|
943
|
+
|
|
944
|
+
return {
|
|
945
|
+
query: `${dateColumn} > :${key}`,
|
|
946
|
+
params: {
|
|
947
|
+
[key]: moment().add(numVal, 'days').format('YYYY-MM-DD'),
|
|
948
|
+
},
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
// ===== BETWEEN =====
|
|
858
952
|
case 'between': {
|
|
859
953
|
if (typeof val === 'string') {
|
|
860
954
|
val = val.split(',').map((v) => v.trim());
|
|
@@ -866,12 +960,12 @@ export class FilterService {
|
|
|
866
960
|
val[0] === '' ||
|
|
867
961
|
val[1] === ''
|
|
868
962
|
) {
|
|
869
|
-
|
|
870
|
-
console.log(`Invalid value for in_between: ${val}`);
|
|
963
|
+
console.log(`Invalid value for between: ${val}`);
|
|
871
964
|
return null;
|
|
872
965
|
}
|
|
966
|
+
|
|
873
967
|
return {
|
|
874
|
-
query:
|
|
968
|
+
query: `${dateColumn} BETWEEN :${key}_start AND :${key}_end`,
|
|
875
969
|
params: {
|
|
876
970
|
[`${key}_start`]: val[0],
|
|
877
971
|
[`${key}_end`]: val[1],
|
|
@@ -879,30 +973,29 @@ export class FilterService {
|
|
|
879
973
|
};
|
|
880
974
|
}
|
|
881
975
|
|
|
976
|
+
// ===== TODAY =====
|
|
882
977
|
case 'today': {
|
|
883
|
-
const today =
|
|
884
|
-
|
|
978
|
+
const today = moment().format('YYYY-MM-DD');
|
|
885
979
|
return {
|
|
886
|
-
query:
|
|
887
|
-
params: {
|
|
888
|
-
today,
|
|
889
|
-
},
|
|
980
|
+
query: `${dateColumn} = :today`,
|
|
981
|
+
params: { today },
|
|
890
982
|
};
|
|
891
983
|
}
|
|
892
984
|
|
|
893
|
-
|
|
985
|
+
// ===== EMPTY =====
|
|
986
|
+
case 'empty':
|
|
987
|
+
case 'is_empty':
|
|
894
988
|
return {
|
|
895
989
|
query: `e.${attr} IS NULL`,
|
|
896
990
|
params: {},
|
|
897
991
|
};
|
|
898
|
-
}
|
|
899
992
|
|
|
900
|
-
case 'not_empty':
|
|
993
|
+
case 'not_empty':
|
|
901
994
|
return {
|
|
902
995
|
query: `e.${attr} IS NOT NULL`,
|
|
903
996
|
params: {},
|
|
904
997
|
};
|
|
905
|
-
|
|
998
|
+
|
|
906
999
|
default:
|
|
907
1000
|
throw new BadRequestException(`Unsupported operator for date: ${op}`);
|
|
908
1001
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Repository } from "typeorm";
|
|
2
|
-
import { EntityJson } from "../entity/entityJson.entity";
|
|
3
|
-
export declare class EntityJSONRepository {
|
|
4
|
-
private readonly entityJSONRepository;
|
|
5
|
-
constructor(entityJSONRepository: Repository<EntityJson>);
|
|
6
|
-
create(flatJson: Partial<EntityJson>): Promise<EntityJson | null>;
|
|
7
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.EntityJSONRepository = void 0;
|
|
16
|
-
const common_1 = require("@nestjs/common");
|
|
17
|
-
const typeorm_1 = require("@nestjs/typeorm");
|
|
18
|
-
const typeorm_2 = require("typeorm");
|
|
19
|
-
const entityJson_entity_1 = require("../entity/entityJson.entity");
|
|
20
|
-
let EntityJSONRepository = class EntityJSONRepository {
|
|
21
|
-
constructor(entityJSONRepository) {
|
|
22
|
-
this.entityJSONRepository = entityJSONRepository;
|
|
23
|
-
}
|
|
24
|
-
async create(flatJson) {
|
|
25
|
-
const { entity_type, entity_id } = flatJson;
|
|
26
|
-
const existing = await this.entityJSONRepository.findOne({
|
|
27
|
-
where: { entity_type, entity_id },
|
|
28
|
-
});
|
|
29
|
-
if (existing) {
|
|
30
|
-
await this.entityJSONRepository.update(existing.id, flatJson);
|
|
31
|
-
return this.entityJSONRepository.findOne({
|
|
32
|
-
where: { id: existing.id },
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
const created = this.entityJSONRepository.create(flatJson);
|
|
36
|
-
return this.entityJSONRepository.save(created);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
exports.EntityJSONRepository = EntityJSONRepository;
|
|
40
|
-
exports.EntityJSONRepository = EntityJSONRepository = __decorate([
|
|
41
|
-
(0, common_1.Injectable)(),
|
|
42
|
-
__param(0, (0, typeorm_1.InjectRepository)(entityJson_entity_1.EntityJson)),
|
|
43
|
-
__metadata("design:paramtypes", [typeorm_2.Repository])
|
|
44
|
-
], EntityJSONRepository);
|
|
45
|
-
//# sourceMappingURL=entityJson.repository.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entityJson.repository.js","sourceRoot":"","sources":["../../../../src/module/entity_json/service/entityJson.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAmD;AACnD,qCAAqC;AACrC,mEAAyD;AAKlD,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAC/B,YAEmB,oBAA4C;QAA5C,yBAAoB,GAApB,oBAAoB,CAAwB;IAC5D,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,QAA6B;QACxC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;QAG5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;YACvD,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;SAClC,CAAC,CAAC;QAEH,IAAI,QAAQ,EAAE,CAAC;YAEb,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAG9D,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;gBACvC,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;aAC3B,CAAC,CAAC;QACL,CAAC;QAGD,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACF,CAAA;AA5BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,0BAAgB,EAAC,8BAAU,CAAC,CAAA;qCACU,oBAAU;GAHxC,oBAAoB,CA4BhC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Injectable } from "@nestjs/common";
|
|
2
|
-
import { InjectRepository } from "@nestjs/typeorm";
|
|
3
|
-
import { Repository } from "typeorm";
|
|
4
|
-
import { EntityJson } from "../entity/entityJson.entity";
|
|
5
|
-
import { create } from "domain";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@Injectable()
|
|
9
|
-
export class EntityJSONRepository {
|
|
10
|
-
constructor(
|
|
11
|
-
@InjectRepository(EntityJson)
|
|
12
|
-
private readonly entityJSONRepository: Repository<EntityJson>,
|
|
13
|
-
) {}
|
|
14
|
-
|
|
15
|
-
async create(flatJson: Partial<EntityJson>) {
|
|
16
|
-
const { entity_type, entity_id } = flatJson;
|
|
17
|
-
|
|
18
|
-
// Step 1 — check if exists by unique keys
|
|
19
|
-
const existing = await this.entityJSONRepository.findOne({
|
|
20
|
-
where: { entity_type, entity_id },
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
if (existing) {
|
|
24
|
-
// Step 2 — normal update (no merge)
|
|
25
|
-
await this.entityJSONRepository.update(existing.id, flatJson);
|
|
26
|
-
|
|
27
|
-
// Optionally return updated row (common practice)
|
|
28
|
-
return this.entityJSONRepository.findOne({
|
|
29
|
-
where: { id: existing.id },
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Step 3 — insert new
|
|
34
|
-
const created = this.entityJSONRepository.create(flatJson);
|
|
35
|
-
return this.entityJSONRepository.save(created);
|
|
36
|
-
}
|
|
37
|
-
}
|