@stamhoofd/backend 2.45.0 → 2.48.0
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/index.ts +2 -0
- package/package.json +10 -10
- package/src/email-recipient-loaders/orders.ts +60 -0
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +19 -1
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +3 -35
- package/src/endpoints/global/members/GetMembersEndpoint.ts +17 -1
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +32 -9
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +14 -1
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +13 -30
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +34 -2
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +2 -0
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersCountEndpoint.ts +4 -12
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +10 -30
- package/src/excel-loaders/organizations.ts +47 -0
- package/src/helpers/AuthenticatedStructures.ts +6 -2
- package/src/helpers/ModelHelper.ts +28 -0
- package/src/helpers/TagHelper.test.ts +373 -0
- package/src/helpers/TagHelper.ts +170 -0
- package/src/seeds/1729253172-update-orders.ts +28 -0
- package/src/sql-filters/members.ts +54 -19
- package/src/sql-filters/orders.ts +42 -7
- package/src/sql-filters/organizations.ts +4 -0
- package/src/sql-filters/payments.ts +1 -0
- package/src/sql-filters/registrations.ts +3 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Organization, Platform } from '@stamhoofd/models';
|
|
2
|
+
import { QueueHandler } from '@stamhoofd/queues';
|
|
3
|
+
import { OrganizationTag, TagHelper as SharedTagHelper } from '@stamhoofd/structures';
|
|
4
|
+
import { ModelHelper } from './ModelHelper';
|
|
5
|
+
|
|
6
|
+
export class TagHelper extends SharedTagHelper {
|
|
7
|
+
static async updateOrganizations() {
|
|
8
|
+
const queueId = 'update-tags-on-organizations';
|
|
9
|
+
QueueHandler.cancel(queueId);
|
|
10
|
+
|
|
11
|
+
await QueueHandler.schedule(queueId, async () => {
|
|
12
|
+
let platform = await Platform.getShared();
|
|
13
|
+
|
|
14
|
+
const tagCounts = new Map<string, number>();
|
|
15
|
+
await this.loopOrganizations(async (organizations) => {
|
|
16
|
+
for (const organization of organizations) {
|
|
17
|
+
organization.meta.tags = this.getAllTagsFromHierarchy(organization.meta.tags, platform.config.tags);
|
|
18
|
+
|
|
19
|
+
for (const tag of organization.meta.tags) {
|
|
20
|
+
tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
await Promise.all(organizations.map(organization => organization.save()));
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Reload platform to avoid race conditions
|
|
28
|
+
platform = await Platform.getShared();
|
|
29
|
+
for (const [tag, count] of tagCounts.entries()) {
|
|
30
|
+
const tagObject = platform.config.tags.find(t => t.id === tag);
|
|
31
|
+
if (tagObject) {
|
|
32
|
+
tagObject.organizationCount = count;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
await platform.save();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private static async loopOrganizations(onBatchReceived: (batch: Organization[]) => Promise<void>) {
|
|
40
|
+
await ModelHelper.loop(Organization, 'id', onBatchReceived, { limit: 10 });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Removes child tag ids that do not exist and sorts the tags.
|
|
45
|
+
* @param platformTags
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
static getCleanedUpTags(platformTags: OrganizationTag[]): OrganizationTag[] {
|
|
49
|
+
const existingTags = new Set(platformTags.map(t => t.id));
|
|
50
|
+
|
|
51
|
+
for (const tag of platformTags) {
|
|
52
|
+
tag.childTags = tag.childTags.filter(tag => existingTags.has(tag));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return this.getSortedTags(platformTags);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private static getSortedTags(tags: OrganizationTag[]): OrganizationTag[] {
|
|
59
|
+
// keep original order, but add child tags below parent tag
|
|
60
|
+
const map = new Map(tags.map(tag => [tag.id, tag]));
|
|
61
|
+
const rootTags = this.getRootTags(tags);
|
|
62
|
+
const sortedTags = this.sortTagsHelper(rootTags, map);
|
|
63
|
+
|
|
64
|
+
return Array.from(sortedTags);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private static sortTagsHelper(tags: OrganizationTag[], allTagsMap: Map<string, OrganizationTag>): Set<OrganizationTag> {
|
|
68
|
+
// set to prevent duplicates
|
|
69
|
+
const result = new Set<OrganizationTag>();
|
|
70
|
+
|
|
71
|
+
for (const tag of tags) {
|
|
72
|
+
result.add(tag);
|
|
73
|
+
if (tag.childTags) {
|
|
74
|
+
const childTags = tag.childTags.map(id => allTagsMap.get(id)).filter(x => x !== undefined);
|
|
75
|
+
this.sortTagsHelper(childTags, allTagsMap).forEach(tag => result.add(tag));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static validateTags(platformTags: OrganizationTag[]): boolean {
|
|
83
|
+
const tagMap = new Map(platformTags.map(tag => [tag.id, tag]));
|
|
84
|
+
|
|
85
|
+
for (const tag of platformTags) {
|
|
86
|
+
const tagId = tag.id;
|
|
87
|
+
|
|
88
|
+
if (tag.childTags.includes(tagId)) {
|
|
89
|
+
// a tag cannot contain itself
|
|
90
|
+
console.error(`Tag ${tag.name} contains itself.`);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let isChildTag = false;
|
|
95
|
+
|
|
96
|
+
for (const otherTag of platformTags) {
|
|
97
|
+
const otherTagId = otherTag.id;
|
|
98
|
+
|
|
99
|
+
if (tagId === otherTagId) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const isChildOfOtherTag = otherTag.childTags.includes(tagId);
|
|
104
|
+
|
|
105
|
+
if (isChildOfOtherTag) {
|
|
106
|
+
if (isChildTag) {
|
|
107
|
+
// a tag can only be a child tag of 1 tag
|
|
108
|
+
console.error(`Tag ${tag.name} is a child tag of multiple tags.`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
isChildTag = true;
|
|
113
|
+
|
|
114
|
+
// infinite loop should not be possible
|
|
115
|
+
// infinite loop if tag contains other tag in hierarchy
|
|
116
|
+
if (this.containsDeep(tagId, otherTagId, { tagMap })) {
|
|
117
|
+
console.error(`Tag ${tag.name} contains an infinite loop with ${otherTag.name}.`);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static getAllTagsFromHierarchy(tagIds: string[], platformTags: OrganizationTag[]) {
|
|
128
|
+
const result = new Set<string>();
|
|
129
|
+
const tagMap = new Map(platformTags.map(tag => [tag.id, tag]));
|
|
130
|
+
|
|
131
|
+
this.recursivelyGetAllTagsFromHierarchy(tagIds, tagMap, result);
|
|
132
|
+
const sorted = Array.from(result);
|
|
133
|
+
|
|
134
|
+
// Sort tags based on platform config order
|
|
135
|
+
sorted.sort((a, b) => {
|
|
136
|
+
const aIndex = platformTags.findIndex(t => t.id === a);
|
|
137
|
+
const bIndex = platformTags.findIndex(t => t.id === b);
|
|
138
|
+
return aIndex - bIndex;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
return sorted;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private static recursivelyGetAllTagsFromHierarchy(tagIds: string[], tagMap: Map<string, OrganizationTag>, result: Set<string>): void {
|
|
145
|
+
for (const tagId of tagIds) {
|
|
146
|
+
const tag = tagMap.get(tagId);
|
|
147
|
+
if (tag) {
|
|
148
|
+
result.add(tagId);
|
|
149
|
+
|
|
150
|
+
const addedChildTags: string[] = [];
|
|
151
|
+
|
|
152
|
+
for (const [otherId, otherTag] of tagMap.entries()) {
|
|
153
|
+
if (otherId === tagId) {
|
|
154
|
+
tagMap.delete(tagId);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (otherTag.childTags.some(childTagId => childTagId === tagId)) {
|
|
158
|
+
if (!result.has(otherId)) {
|
|
159
|
+
addedChildTags.push(otherId);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (addedChildTags.length > 0) {
|
|
165
|
+
this.recursivelyGetAllTagsFromHierarchy(addedChildTags, tagMap, result);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
+
import { Order } from '@stamhoofd/models';
|
|
3
|
+
import { sleep } from '@stamhoofd/utility';
|
|
4
|
+
import { ModelHelper } from '../helpers/ModelHelper';
|
|
5
|
+
|
|
6
|
+
export default new Migration(async () => {
|
|
7
|
+
if (STAMHOOFD.environment === 'test') {
|
|
8
|
+
console.log('skipped in tests');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
console.log('Start saving orders.');
|
|
13
|
+
|
|
14
|
+
const limit = 100;
|
|
15
|
+
let count = limit;
|
|
16
|
+
|
|
17
|
+
await ModelHelper.loop(Order, 'id', async (batch: Order[]) => {
|
|
18
|
+
console.log('Saving orders...', `(${count})`);
|
|
19
|
+
// save all orders to update the new columns
|
|
20
|
+
await Promise.all(batch.map(order => order.save()));
|
|
21
|
+
count += limit;
|
|
22
|
+
},
|
|
23
|
+
{ limit });
|
|
24
|
+
|
|
25
|
+
await sleep(1000);
|
|
26
|
+
|
|
27
|
+
console.log('Finished saving orders.');
|
|
28
|
+
});
|
|
@@ -8,26 +8,26 @@ import { registrationFilterCompilers } from './registrations';
|
|
|
8
8
|
*/
|
|
9
9
|
export const memberFilterCompilers: SQLFilterDefinitions = {
|
|
10
10
|
...baseSQLFilterCompilers,
|
|
11
|
-
id: createSQLColumnFilterCompiler('id'),
|
|
12
|
-
memberNumber: createSQLColumnFilterCompiler('memberNumber'),
|
|
13
|
-
firstName: createSQLColumnFilterCompiler('firstName'),
|
|
14
|
-
lastName: createSQLColumnFilterCompiler('lastName'),
|
|
15
|
-
name: createSQLExpressionFilterCompiler(
|
|
11
|
+
'id': createSQLColumnFilterCompiler('id'),
|
|
12
|
+
'memberNumber': createSQLColumnFilterCompiler('memberNumber'),
|
|
13
|
+
'firstName': createSQLColumnFilterCompiler('firstName'),
|
|
14
|
+
'lastName': createSQLColumnFilterCompiler('lastName'),
|
|
15
|
+
'name': createSQLExpressionFilterCompiler(
|
|
16
16
|
new SQLConcat(
|
|
17
17
|
SQL.column('firstName'),
|
|
18
18
|
new SQLScalar(' '),
|
|
19
19
|
SQL.column('lastName'),
|
|
20
20
|
),
|
|
21
21
|
),
|
|
22
|
-
age: createSQLExpressionFilterCompiler(
|
|
22
|
+
'age': createSQLExpressionFilterCompiler(
|
|
23
23
|
new SQLAge(SQL.column('birthDay')),
|
|
24
24
|
{ nullable: true },
|
|
25
25
|
),
|
|
26
|
-
gender: createSQLExpressionFilterCompiler(
|
|
26
|
+
'gender': createSQLExpressionFilterCompiler(
|
|
27
27
|
SQL.jsonValue(SQL.column('details'), '$.value.gender'),
|
|
28
28
|
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
29
29
|
),
|
|
30
|
-
birthDay: createSQLColumnFilterCompiler('birthDay', {
|
|
30
|
+
'birthDay': createSQLColumnFilterCompiler('birthDay', {
|
|
31
31
|
normalizeValue: (d) => {
|
|
32
32
|
if (typeof d === 'number') {
|
|
33
33
|
const date = new Date(d);
|
|
@@ -36,41 +36,76 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
|
|
|
36
36
|
return d;
|
|
37
37
|
},
|
|
38
38
|
}),
|
|
39
|
-
organizationName: createSQLExpressionFilterCompiler(
|
|
39
|
+
'organizationName': createSQLExpressionFilterCompiler(
|
|
40
40
|
SQL.column('organizations', 'name'),
|
|
41
41
|
),
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
'details.requiresFinancialSupport': createSQLExpressionFilterCompiler(
|
|
44
|
+
SQL.jsonValue(SQL.column('details'), '$.value.requiresFinancialSupport.value'),
|
|
45
|
+
{ isJSONValue: true, type: SQLValueType.JSONBoolean },
|
|
46
|
+
),
|
|
47
|
+
|
|
48
|
+
'email': createSQLExpressionFilterCompiler(
|
|
44
49
|
SQL.jsonValue(SQL.column('details'), '$.value.email'),
|
|
45
50
|
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
46
51
|
),
|
|
47
52
|
|
|
48
|
-
parentEmail: createSQLExpressionFilterCompiler(
|
|
53
|
+
'parentEmail': createSQLExpressionFilterCompiler(
|
|
49
54
|
SQL.jsonValue(SQL.column('details'), '$.value.parents[*].email'),
|
|
50
55
|
{ isJSONValue: true, isJSONObject: true, type: SQLValueType.JSONString },
|
|
51
56
|
),
|
|
52
57
|
|
|
53
|
-
unverifiedEmail: createSQLExpressionFilterCompiler(
|
|
58
|
+
'unverifiedEmail': createSQLExpressionFilterCompiler(
|
|
54
59
|
SQL.jsonValue(SQL.column('details'), '$.value.unverifiedEmails'),
|
|
55
60
|
{ isJSONValue: true, isJSONObject: true, type: SQLValueType.JSONString },
|
|
56
61
|
),
|
|
57
62
|
|
|
58
|
-
phone: createSQLExpressionFilterCompiler(
|
|
63
|
+
'phone': createSQLExpressionFilterCompiler(
|
|
59
64
|
SQL.jsonValue(SQL.column('details'), '$.value.phone'),
|
|
60
65
|
{ isJSONValue: true },
|
|
61
66
|
),
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
'details.address': createSQLFilterNamespace({
|
|
69
|
+
city: createSQLExpressionFilterCompiler(
|
|
70
|
+
SQL.jsonValue(SQL.column('details'), '$.value.address.city'),
|
|
71
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
72
|
+
),
|
|
73
|
+
postalCode: createSQLExpressionFilterCompiler(
|
|
74
|
+
SQL.jsonValue(SQL.column('details'), '$.value.address.postalCode'),
|
|
75
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
76
|
+
),
|
|
77
|
+
street: createSQLExpressionFilterCompiler(
|
|
78
|
+
SQL.jsonValue(SQL.column('details'), '$.value.address.street'),
|
|
79
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
80
|
+
),
|
|
81
|
+
}),
|
|
82
|
+
|
|
83
|
+
'details.parents[*].address': createSQLFilterNamespace({
|
|
84
|
+
city: createSQLExpressionFilterCompiler(
|
|
85
|
+
SQL.jsonValue(SQL.column('details'), '$.value.parents[*].address.city'),
|
|
86
|
+
{ isJSONValue: true, isJSONObject: true },
|
|
87
|
+
),
|
|
88
|
+
postalCode: createSQLExpressionFilterCompiler(
|
|
89
|
+
SQL.jsonValue(SQL.column('details'), '$.value.parents[*].address.postalCode'),
|
|
90
|
+
{ isJSONValue: true, isJSONObject: true },
|
|
91
|
+
),
|
|
92
|
+
street: createSQLExpressionFilterCompiler(
|
|
93
|
+
SQL.jsonValue(SQL.column('details'), '$.value.parents[*].address.street'),
|
|
94
|
+
{ isJSONValue: true, isJSONObject: true },
|
|
95
|
+
),
|
|
96
|
+
}),
|
|
97
|
+
|
|
98
|
+
'parentPhone': createSQLExpressionFilterCompiler(
|
|
64
99
|
SQL.jsonValue(SQL.column('details'), '$.value.parents[*].phone'),
|
|
65
100
|
{ isJSONValue: true, isJSONObject: true },
|
|
66
101
|
),
|
|
67
102
|
|
|
68
|
-
unverifiedPhone: createSQLExpressionFilterCompiler(
|
|
103
|
+
'unverifiedPhone': createSQLExpressionFilterCompiler(
|
|
69
104
|
SQL.jsonValue(SQL.column('details'), '$.value.unverifiedPhones'),
|
|
70
105
|
{ isJSONValue: true, isJSONObject: true },
|
|
71
106
|
),
|
|
72
107
|
|
|
73
|
-
registrations: createSQLRelationFilterCompiler(
|
|
108
|
+
'registrations': createSQLRelationFilterCompiler(
|
|
74
109
|
SQL.select()
|
|
75
110
|
.from(
|
|
76
111
|
SQL.table('registrations'),
|
|
@@ -109,7 +144,7 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
|
|
|
109
144
|
},
|
|
110
145
|
),
|
|
111
146
|
|
|
112
|
-
responsibilities: createSQLRelationFilterCompiler(
|
|
147
|
+
'responsibilities': createSQLRelationFilterCompiler(
|
|
113
148
|
SQL.select()
|
|
114
149
|
.from(
|
|
115
150
|
SQL.table('member_responsibility_records'),
|
|
@@ -151,7 +186,7 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
|
|
|
151
186
|
},
|
|
152
187
|
),
|
|
153
188
|
|
|
154
|
-
platformMemberships: createSQLRelationFilterCompiler(
|
|
189
|
+
'platformMemberships': createSQLRelationFilterCompiler(
|
|
155
190
|
SQL.select()
|
|
156
191
|
.from(
|
|
157
192
|
SQL.table('member_platform_memberships'),
|
|
@@ -178,7 +213,7 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
|
|
|
178
213
|
},
|
|
179
214
|
),
|
|
180
215
|
|
|
181
|
-
organizations: createSQLRelationFilterCompiler(
|
|
216
|
+
'organizations': createSQLRelationFilterCompiler(
|
|
182
217
|
SQL.select()
|
|
183
218
|
.from(
|
|
184
219
|
SQL.table('registrations'),
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import { baseSQLFilterCompilers, createSQLColumnFilterCompiler, createSQLExpressionFilterCompiler, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
1
|
+
import { baseSQLFilterCompilers, createSQLColumnFilterCompiler, createSQLExpressionFilterCompiler, SQL, SQLConcat, SQLFilterDefinitions, SQLScalar, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const orderFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
+
// only backend (not useful to filter on these in the frontend)
|
|
5
6
|
organizationId: createSQLColumnFilterCompiler('organizationId'),
|
|
7
|
+
updatedAt: createSQLColumnFilterCompiler('updatedAt'),
|
|
8
|
+
|
|
9
|
+
// frontend and backend
|
|
10
|
+
webshopId: createSQLColumnFilterCompiler('webshopId'),
|
|
6
11
|
id: createSQLColumnFilterCompiler('id'),
|
|
12
|
+
timeSlotEndTime: createSQLExpressionFilterCompiler(
|
|
13
|
+
SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.endTime'),
|
|
14
|
+
// todo: type?
|
|
15
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
16
|
+
),
|
|
17
|
+
timeSlotStartTime: createSQLExpressionFilterCompiler(
|
|
18
|
+
SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.startTime'),
|
|
19
|
+
// todo: type?
|
|
20
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
21
|
+
),
|
|
22
|
+
createdAt: createSQLColumnFilterCompiler('createdAt'),
|
|
7
23
|
number: createSQLColumnFilterCompiler('number'),
|
|
8
24
|
status: createSQLColumnFilterCompiler('status'),
|
|
9
25
|
paymentMethod: createSQLExpressionFilterCompiler(
|
|
@@ -19,15 +35,34 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
|
|
|
19
35
|
// todo: type?
|
|
20
36
|
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
21
37
|
),
|
|
22
|
-
|
|
23
|
-
|
|
38
|
+
validAt: createSQLColumnFilterCompiler('validAt'),
|
|
39
|
+
|
|
40
|
+
// todo: TEST!
|
|
41
|
+
name: createSQLExpressionFilterCompiler(
|
|
42
|
+
new SQLConcat(
|
|
43
|
+
SQL.jsonValue(SQL.column('data'), '$.value.customer.firstName'),
|
|
44
|
+
new SQLScalar(' '),
|
|
45
|
+
SQL.jsonValue(SQL.column('data'), '$.value.customer.lastName'),
|
|
46
|
+
),
|
|
47
|
+
// SQL.jsonValue(SQL.column('data'), '$.value.customer.name'),
|
|
24
48
|
// todo: type?
|
|
25
49
|
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
26
50
|
),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
email: createSQLExpressionFilterCompiler(
|
|
52
|
+
SQL.jsonValue(SQL.column('data'), '$.value.customer.email'),
|
|
53
|
+
// todo: type?
|
|
54
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
55
|
+
),
|
|
56
|
+
phone: createSQLExpressionFilterCompiler(
|
|
57
|
+
SQL.jsonValue(SQL.column('data'), '$.value.customer.phone'),
|
|
30
58
|
// todo: type?
|
|
31
|
-
{ isJSONValue: true },
|
|
59
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
32
60
|
),
|
|
61
|
+
totalPrice: createSQLColumnFilterCompiler('totalPrice'),
|
|
62
|
+
amount: createSQLColumnFilterCompiler('amount'),
|
|
63
|
+
timeSlotTime: createSQLColumnFilterCompiler('timeSlotTime'),
|
|
64
|
+
|
|
65
|
+
// only frontend
|
|
66
|
+
// openBalance
|
|
67
|
+
// location
|
|
33
68
|
};
|
|
@@ -33,6 +33,10 @@ export const organizationFilterCompilers: SQLFilterDefinitions = {
|
|
|
33
33
|
SQL.jsonValue(SQL.column('organizations', 'address'), '$.value.city'),
|
|
34
34
|
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
35
35
|
),
|
|
36
|
+
postalCode: createSQLExpressionFilterCompiler(
|
|
37
|
+
SQL.jsonValue(SQL.column('organizations', 'address'), '$.value.postalCode'),
|
|
38
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
39
|
+
),
|
|
36
40
|
country: createSQLExpressionFilterCompiler(
|
|
37
41
|
SQL.jsonValue(
|
|
38
42
|
SQL.column('organizations', 'address'),
|
|
@@ -15,6 +15,7 @@ export const paymentFilterCompilers: SQLFilterDefinitions = {
|
|
|
15
15
|
paidAt: createSQLColumnFilterCompiler('paidAt', { nullable: true }),
|
|
16
16
|
price: createSQLColumnFilterCompiler('price'),
|
|
17
17
|
provider: createSQLColumnFilterCompiler('provider', { nullable: true }),
|
|
18
|
+
transferDescription: createSQLColumnFilterCompiler('transferDescription', { nullable: true }),
|
|
18
19
|
customer: createSQLFilterNamespace({
|
|
19
20
|
...baseSQLFilterCompilers,
|
|
20
21
|
email: createSQLExpressionFilterCompiler(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SQLFilterDefinitions, baseSQLFilterCompilers, createSQLColumnFilterCompiler, SQL, createSQLFilterNamespace, createSQLExpressionFilterCompiler } from '@stamhoofd/sql';
|
|
1
|
+
import { SQLFilterDefinitions, baseSQLFilterCompilers, createSQLColumnFilterCompiler, SQL, createSQLFilterNamespace, createSQLExpressionFilterCompiler, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const registrationFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
@@ -15,9 +15,11 @@ export const registrationFilterCompilers: SQLFilterDefinitions = {
|
|
|
15
15
|
id: createSQLColumnFilterCompiler('groupId'),
|
|
16
16
|
name: createSQLExpressionFilterCompiler(
|
|
17
17
|
SQL.jsonValue(SQL.column('groups', 'settings'), '$.value.name'),
|
|
18
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
18
19
|
),
|
|
19
20
|
status: createSQLExpressionFilterCompiler(
|
|
20
21
|
SQL.column('groups', 'status'),
|
|
22
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
21
23
|
),
|
|
22
24
|
defaultAgeGroupId: createSQLColumnFilterCompiler(SQL.column('groups', 'defaultAgeGroupId'), { nullable: true }),
|
|
23
25
|
}),
|