@stamhoofd/backend 2.108.0 → 2.110.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.
Files changed (38) hide show
  1. package/index.ts +2 -2
  2. package/package.json +20 -20
  3. package/src/crons/disable-auto-update-documents.test.ts +164 -0
  4. package/src/crons/disable-auto-update-documents.ts +82 -0
  5. package/src/endpoints/global/members/GetMembersEndpoint.ts +5 -5
  6. package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +8 -7
  7. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +9 -8
  8. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesCountEndpoint.ts +48 -0
  9. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +95 -19
  10. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.test.ts +282 -0
  11. package/src/endpoints/organization/dashboard/documents/{PatchDocumentTemplateEndpoint.ts → PatchDocumentTemplatesEndpoint.ts} +56 -3
  12. package/src/excel-loaders/members.ts +61 -7
  13. package/src/excel-loaders/registrations.ts +123 -2
  14. package/src/helpers/LimitedFilteredRequestHelper.ts +24 -0
  15. package/src/helpers/SQLTranslatedString.ts +14 -0
  16. package/src/helpers/TagHelper.test.ts +9 -9
  17. package/src/helpers/outstandingBalanceJoin.ts +49 -0
  18. package/src/seeds/1765896674-document-update-year.test.ts +179 -0
  19. package/src/seeds/1765896674-document-update-year.ts +66 -0
  20. package/src/seeds/1766150402-document-published-at.test.ts +46 -0
  21. package/src/seeds/1766150402-document-published-at.ts +20 -0
  22. package/src/services/PaymentService.ts +14 -32
  23. package/src/sql-filters/base-registration-filter-compilers.ts +51 -4
  24. package/src/sql-filters/document-templates.ts +45 -0
  25. package/src/sql-filters/documents.ts +1 -1
  26. package/src/sql-filters/events.ts +6 -6
  27. package/src/sql-filters/groups.ts +7 -6
  28. package/src/sql-filters/members.ts +31 -26
  29. package/src/sql-filters/orders.ts +16 -16
  30. package/src/sql-filters/organizations.ts +11 -11
  31. package/src/sql-filters/payments.ts +10 -10
  32. package/src/sql-filters/registrations.ts +14 -6
  33. package/src/sql-sorters/document-templates.ts +79 -0
  34. package/src/sql-sorters/documents.ts +1 -1
  35. package/src/sql-sorters/members.ts +22 -0
  36. package/src/sql-sorters/orders.ts +5 -5
  37. package/src/sql-sorters/organizations.ts +3 -3
  38. package/src/sql-sorters/registrations.ts +186 -15
@@ -1,4 +1,5 @@
1
- import { baseSQLFilterCompilers, createColumnFilter, createWildcardColumnFilter, SQL, SQLJsonExtract, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
1
+ import { baseSQLFilterCompilers, createColumnFilter, createWildcardColumnFilter, SQL, SQLFilterDefinitions, SQLJsonExtract, SQLValueType } from '@stamhoofd/sql';
2
+ import { SQLTranslatedString } from '../helpers/SQLTranslatedString.js';
2
3
 
3
4
  export const groupFilterCompilers: SQLFilterDefinitions = {
4
5
  ...baseSQLFilterCompilers,
@@ -18,9 +19,9 @@ export const groupFilterCompilers: SQLFilterDefinitions = {
18
19
  nullable: false,
19
20
  }),
20
21
  name: createColumnFilter({
21
- expression: SQL.jsonValue(SQL.column('settings'), '$.value.name'),
22
- type: SQLValueType.JSONString,
23
- nullable: false,
22
+ expression: new SQLTranslatedString(SQL.column('settings'), '$.value.name'),
23
+ type: SQLValueType.String,
24
+ nullable: true,
24
25
  }),
25
26
  status: createColumnFilter({
26
27
  expression: SQL.column('status'),
@@ -34,14 +35,14 @@ export const groupFilterCompilers: SQLFilterDefinitions = {
34
35
  }),
35
36
  bundleDiscounts: createWildcardColumnFilter(
36
37
  (key: string) => ({
37
- expression: SQL.jsonValue(SQL.column('settings'), `$.value.prices[*].bundleDiscounts.${SQLJsonExtract.escapePathComponent(key)}`, true),
38
+ expression: SQL.jsonExtract(SQL.column('settings'), `$.value.prices[*].bundleDiscounts.${SQLJsonExtract.escapePathComponent(key)}`, true),
38
39
  type: SQLValueType.JSONArray,
39
40
  nullable: true,
40
41
  }),
41
42
  (key: string) => ({
42
43
  ...baseSQLFilterCompilers,
43
44
  name: createColumnFilter({
44
- expression: SQL.jsonValue(SQL.column('settings'), `$.value.prices[*].bundleDiscounts.${SQLJsonExtract.escapePathComponent(key)}.name`, true),
45
+ expression: SQL.jsonExtract(SQL.column('settings'), `$.value.prices[*].bundleDiscounts.${SQLJsonExtract.escapePathComponent(key)}.name`, true),
45
46
  type: SQLValueType.JSONArray,
46
47
  nullable: true,
47
48
  }),
@@ -1,10 +1,10 @@
1
1
  import { SimpleError } from '@simonbackx/simple-errors';
2
2
  import { Email, Member } from '@stamhoofd/models';
3
- import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLAge, SQLCast, SQLConcat, SQLFilterDefinitions, SQLValueType, SQLScalar, createWildcardColumnFilter, SQLJsonExtract } from '@stamhoofd/sql';
3
+ import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, createWildcardColumnFilter, SQL, SQLAge, SQLCast, SQLConcat, SQLFilterDefinitions, SQLJsonExtract, SQLScalar, SQLValueType } from '@stamhoofd/sql';
4
4
  import { AccessRight } from '@stamhoofd/structures';
5
- import { Context } from '../helpers/Context';
6
- import { baseRegistrationFilterCompilers } from './base-registration-filter-compilers';
7
- import { organizationFilterCompilers } from './organizations';
5
+ import { Context } from '../helpers/Context.js';
6
+ import { baseRegistrationFilterCompilers } from './base-registration-filter-compilers.js';
7
+ import { organizationFilterCompilers } from './organizations.js';
8
8
 
9
9
  const membersTable = SQL.table(Member.table);
10
10
 
@@ -20,7 +20,7 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
20
20
  }),
21
21
  'memberNumber': createColumnFilter({
22
22
  expression: SQL.column(membersTable, 'memberNumber'),
23
- type: SQLValueType.Number,
23
+ type: SQLValueType.String,
24
24
  nullable: true,
25
25
  }),
26
26
  'firstName': createColumnFilter({
@@ -48,7 +48,7 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
48
48
  nullable: true,
49
49
  }),
50
50
  'gender': createColumnFilter({
51
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.gender'),
51
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.gender'),
52
52
  type: SQLValueType.JSONString,
53
53
  nullable: false,
54
54
  }),
@@ -58,13 +58,18 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
58
58
  type: SQLValueType.Datetime,
59
59
  nullable: true,
60
60
  }),
61
+ 'createdAt': createColumnFilter({
62
+ expression: SQL.column(membersTable, 'createdAt'),
63
+ type: SQLValueType.Datetime,
64
+ nullable: false,
65
+ }),
61
66
  'organizationName': createColumnFilter({
62
67
  expression: SQL.column('organizations', 'name'),
63
68
  type: SQLValueType.String,
64
69
  nullable: false,
65
70
  }),
66
71
  'details.requiresFinancialSupport': createColumnFilter({
67
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.requiresFinancialSupport.value'),
72
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.requiresFinancialSupport.value'),
68
73
  type: SQLValueType.JSONBoolean,
69
74
  nullable: true,
70
75
  checkPermission: async () => {
@@ -94,12 +99,12 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
94
99
  },
95
100
  }),
96
101
  'email': createColumnFilter({
97
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.email'),
102
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.email'),
98
103
  type: SQLValueType.JSONString,
99
104
  nullable: true,
100
105
  }),
101
106
  'parentEmail': createColumnFilter({
102
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.parents[*].email'),
107
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.parents[*].email'),
103
108
  type: SQLValueType.JSONArray,
104
109
  nullable: true,
105
110
  }),
@@ -132,34 +137,34 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
132
137
  }),
133
138
  },
134
139
  'unverifiedEmail': createColumnFilter({
135
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.unverifiedEmails'),
140
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.unverifiedEmails'),
136
141
  type: SQLValueType.JSONArray,
137
142
  nullable: true,
138
143
  }),
139
144
  'phone': createColumnFilter({
140
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.phone'),
145
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.phone'),
141
146
  type: SQLValueType.JSONString,
142
147
  nullable: true,
143
148
  }),
144
149
  'details.address': {
145
150
  ...baseSQLFilterCompilers,
146
151
  city: createColumnFilter({
147
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.address.city'),
152
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.address.city'),
148
153
  type: SQLValueType.JSONString,
149
154
  nullable: true,
150
155
  }),
151
156
  postalCode: createColumnFilter({
152
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.address.postalCode'),
157
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.address.postalCode'),
153
158
  type: SQLValueType.JSONString,
154
159
  nullable: true,
155
160
  }),
156
161
  street: createColumnFilter({
157
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.address.street'),
162
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.address.street'),
158
163
  type: SQLValueType.JSONString,
159
164
  nullable: true,
160
165
  }),
161
166
  number: createColumnFilter({
162
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.address.number'),
167
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.address.number'),
163
168
  type: SQLValueType.JSONString,
164
169
  nullable: true,
165
170
  }),
@@ -167,33 +172,33 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
167
172
  'details.parents[*].address': {
168
173
  ...baseSQLFilterCompilers,
169
174
  city: createColumnFilter({
170
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.parents[*].address.city'),
175
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.parents[*].address.city'),
171
176
  type: SQLValueType.JSONArray,
172
177
  nullable: true,
173
178
  }),
174
179
  postalCode: createColumnFilter({
175
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.parents[*].address.postalCode'),
180
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.parents[*].address.postalCode'),
176
181
  type: SQLValueType.JSONArray,
177
182
  nullable: true,
178
183
  }),
179
184
  street: createColumnFilter({
180
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.parents[*].address.street'),
185
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.parents[*].address.street'),
181
186
  type: SQLValueType.JSONArray,
182
187
  nullable: true,
183
188
  }),
184
189
  number: createColumnFilter({
185
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.parents[*].address.number'),
190
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.parents[*].address.number'),
186
191
  type: SQLValueType.JSONArray,
187
192
  nullable: true,
188
193
  }),
189
194
  },
190
195
  'parentPhone': createColumnFilter({
191
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.parents[*].phone'),
196
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.parents[*].phone'),
192
197
  type: SQLValueType.JSONArray,
193
198
  nullable: true,
194
199
  }),
195
200
  'unverifiedPhone': createColumnFilter({
196
- expression: SQL.jsonValue(SQL.column(membersTable, 'details'), '$.value.unverifiedPhones'),
201
+ expression: SQL.jsonExtract(SQL.column(membersTable, 'details'), '$.value.unverifiedPhones'),
197
202
  type: SQLValueType.JSONArray,
198
203
  nullable: true,
199
204
  }),
@@ -458,21 +463,21 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
458
463
  ...baseSQLFilterCompilers,
459
464
  recordAnswers: createWildcardColumnFilter(
460
465
  (key: string) => ({
461
- expression: SQL.jsonValue(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}`, true),
466
+ expression: SQL.jsonExtract(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}`, true),
462
467
  type: SQLValueType.JSONObject,
463
468
  nullable: true,
464
469
  }),
465
470
  (key: string) => ({
466
471
  ...baseSQLFilterCompilers,
467
472
  selected: createColumnFilter({
468
- expression: SQL.jsonValue(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selected`, true),
473
+ expression: SQL.jsonExtract(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selected`, true),
469
474
  type: SQLValueType.JSONBoolean,
470
475
  nullable: true,
471
476
  }),
472
477
  selectedChoice: {
473
478
  ...baseSQLFilterCompilers,
474
479
  id: createColumnFilter({
475
- expression: SQL.jsonValue(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoice.id`, true),
480
+ expression: SQL.jsonExtract(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoice.id`, true),
476
481
  type: SQLValueType.JSONString,
477
482
  nullable: true,
478
483
  }),
@@ -480,13 +485,13 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
480
485
  selectedChoices: {
481
486
  ...baseSQLFilterCompilers,
482
487
  id: createColumnFilter({
483
- expression: SQL.jsonValue(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoices[*].id`, true),
488
+ expression: SQL.jsonExtract(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoices[*].id`, true),
484
489
  type: SQLValueType.JSONArray,
485
490
  nullable: true,
486
491
  }),
487
492
  },
488
493
  value: createColumnFilter({
489
- expression: SQL.jsonValue(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.value`, true),
494
+ expression: SQL.jsonExtract(SQL.column('details'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.value`, true),
490
495
  type: SQLValueType.JSONString,
491
496
  nullable: true,
492
497
  }),
@@ -1,4 +1,4 @@
1
- import { baseSQLFilterCompilers, createColumnFilter, SQL, SQLCast, SQLConcat, SQLJsonUnquote, SQLFilterDefinitions, SQLValueType, SQLScalar, createExistsFilter, createWildcardColumnFilter, SQLJsonExtract } from '@stamhoofd/sql';
1
+ import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, createWildcardColumnFilter, SQL, SQLCast, SQLConcat, SQLFilterDefinitions, SQLJsonExtract, SQLJsonUnquote, SQLScalar, SQLValueType } from '@stamhoofd/sql';
2
2
 
3
3
  export const orderFilterCompilers: SQLFilterDefinitions = {
4
4
  ...baseSQLFilterCompilers,
@@ -26,12 +26,12 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
26
26
  nullable: false,
27
27
  }),
28
28
  timeSlotEndTime: createColumnFilter({
29
- expression: SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.endTime'),
29
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.timeSlot.endTime'),
30
30
  type: SQLValueType.JSONString,
31
31
  nullable: true,
32
32
  }),
33
33
  timeSlotStartTime: createColumnFilter({
34
- expression: SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.startTime'),
34
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.timeSlot.startTime'),
35
35
  type: SQLValueType.JSONString,
36
36
  nullable: true,
37
37
  }),
@@ -51,17 +51,17 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
51
51
  nullable: false,
52
52
  }),
53
53
  paymentMethod: createColumnFilter({
54
- expression: SQL.jsonValue(SQL.column('data'), '$.value.paymentMethod'),
54
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.paymentMethod'),
55
55
  type: SQLValueType.JSONString,
56
56
  nullable: false,
57
57
  }),
58
58
  checkoutMethod: createColumnFilter({
59
- expression: SQL.jsonValue(SQL.column('data'), '$.value.checkoutMethod.type'),
59
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.checkoutMethod.type'),
60
60
  type: SQLValueType.JSONString,
61
61
  nullable: true,
62
62
  }),
63
63
  timeSlotDate: createColumnFilter({
64
- expression: SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.date'),
64
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.timeSlot.date'),
65
65
  type: SQLValueType.JSONString,
66
66
  nullable: true,
67
67
  }),
@@ -73,21 +73,21 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
73
73
  name: createColumnFilter({
74
74
  expression: new SQLCast(
75
75
  new SQLConcat(
76
- new SQLJsonUnquote(SQL.jsonValue(SQL.column('data'), '$.value.customer.firstName')),
76
+ new SQLJsonUnquote(SQL.jsonExtract(SQL.column('data'), '$.value.customer.firstName')),
77
77
  new SQLScalar(' '),
78
- new SQLJsonUnquote(SQL.jsonValue(SQL.column('data'), '$.value.customer.lastName')),
78
+ new SQLJsonUnquote(SQL.jsonExtract(SQL.column('data'), '$.value.customer.lastName')),
79
79
  ),
80
80
  'CHAR'),
81
81
  type: SQLValueType.String,
82
82
  nullable: false,
83
83
  }),
84
84
  email: createColumnFilter({
85
- expression: SQL.jsonValue(SQL.column('data'), '$.value.customer.email'),
85
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.customer.email'),
86
86
  type: SQLValueType.JSONString,
87
87
  nullable: false,
88
88
  }),
89
89
  phone: createColumnFilter({
90
- expression: SQL.jsonValue(SQL.column('data'), '$.value.customer.phone'),
90
+ expression: SQL.jsonExtract(SQL.column('data'), '$.value.customer.phone'),
91
91
  type: SQLValueType.JSONString,
92
92
  nullable: false,
93
93
  }),
@@ -119,7 +119,7 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
119
119
  .join(
120
120
  SQL.join(
121
121
  SQL.jsonTable(
122
- SQL.jsonValue(SQL.column('innerOrders', 'data'), '$.value.cart.items'),
122
+ SQL.jsonExtract(SQL.column('innerOrders', 'data'), '$.value.cart.items'),
123
123
  'items',
124
124
  )
125
125
  .addColumn(
@@ -168,21 +168,21 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
168
168
 
169
169
  recordAnswers: createWildcardColumnFilter(
170
170
  (key: string) => ({
171
- expression: SQL.jsonValue(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}`, true),
171
+ expression: SQL.jsonExtract(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}`, true),
172
172
  type: SQLValueType.JSONObject,
173
173
  nullable: true,
174
174
  }),
175
175
  (key: string) => ({
176
176
  ...baseSQLFilterCompilers,
177
177
  selected: createColumnFilter({
178
- expression: SQL.jsonValue(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selected`, true),
178
+ expression: SQL.jsonExtract(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selected`, true),
179
179
  type: SQLValueType.JSONBoolean,
180
180
  nullable: true,
181
181
  }),
182
182
  selectedChoice: {
183
183
  ...baseSQLFilterCompilers,
184
184
  id: createColumnFilter({
185
- expression: SQL.jsonValue(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoice.id`, true),
185
+ expression: SQL.jsonExtract(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoice.id`, true),
186
186
  type: SQLValueType.JSONString,
187
187
  nullable: true,
188
188
  }),
@@ -190,13 +190,13 @@ export const orderFilterCompilers: SQLFilterDefinitions = {
190
190
  selectedChoices: {
191
191
  ...baseSQLFilterCompilers,
192
192
  id: createColumnFilter({
193
- expression: SQL.jsonValue(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoices[*].id`, true),
193
+ expression: SQL.jsonExtract(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.selectedChoices[*].id`, true),
194
194
  type: SQLValueType.JSONArray,
195
195
  nullable: true,
196
196
  }),
197
197
  },
198
198
  value: createColumnFilter({
199
- expression: SQL.jsonValue(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.value`, true),
199
+ expression: SQL.jsonExtract(SQL.column('data'), `$.value.recordAnswers.${SQLJsonExtract.escapePathComponent(key)}.value`, true),
200
200
  type: SQLValueType.JSONString,
201
201
  nullable: true,
202
202
  }),
@@ -1,4 +1,4 @@
1
- import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLConcat, SQLFilterDefinitions, SQLValueType, SQLNow, SQLNull, SQLScalar, SQLWhereEqual, SQLWhereOr, SQLWhereSign } from '@stamhoofd/sql';
1
+ import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLConcat, SQLFilterDefinitions, SQLNow, SQLNull, SQLScalar, SQLValueType, SQLWhereEqual, SQLWhereOr, SQLWhereSign } from '@stamhoofd/sql';
2
2
  import { SetupStepType } from '@stamhoofd/structures';
3
3
 
4
4
  export const organizationFilterCompilers: SQLFilterDefinitions = {
@@ -29,32 +29,32 @@ export const organizationFilterCompilers: SQLFilterDefinitions = {
29
29
  nullable: false,
30
30
  }),
31
31
  city: createColumnFilter({
32
- expression: SQL.jsonValue(SQL.column('organizations', 'address'), '$.value.city'),
32
+ expression: SQL.jsonExtract(SQL.column('organizations', 'address'), '$.value.city'),
33
33
  type: SQLValueType.JSONString,
34
34
  nullable: false,
35
35
  }),
36
36
  postalCode: createColumnFilter({
37
- expression: SQL.jsonValue(SQL.column('organizations', 'address'), '$.value.postalCode'),
37
+ expression: SQL.jsonExtract(SQL.column('organizations', 'address'), '$.value.postalCode'),
38
38
  type: SQLValueType.JSONString,
39
39
  nullable: false,
40
40
  }),
41
41
  country: createColumnFilter({
42
- expression: SQL.jsonValue(SQL.column('organizations', 'address'), '$.value.country'),
42
+ expression: SQL.jsonExtract(SQL.column('organizations', 'address'), '$.value.country'),
43
43
  type: SQLValueType.JSONString,
44
44
  nullable: false,
45
45
  }),
46
46
  umbrellaOrganization: createColumnFilter({
47
- expression: SQL.jsonValue(SQL.column('organizations', 'meta'), '$.value.umbrellaOrganization'),
47
+ expression: SQL.jsonExtract(SQL.column('organizations', 'meta'), '$.value.umbrellaOrganization'),
48
48
  type: SQLValueType.JSONString,
49
49
  nullable: true,
50
50
  }),
51
51
  type: createColumnFilter({
52
- expression: SQL.jsonValue(SQL.column('organizations', 'meta'), '$.value.type'),
52
+ expression: SQL.jsonExtract(SQL.column('organizations', 'meta'), '$.value.type'),
53
53
  type: SQLValueType.JSONString,
54
54
  nullable: false,
55
55
  }),
56
56
  tags: createColumnFilter({
57
- expression: SQL.jsonValue(SQL.column('organizations', 'meta'), '$.value.tags'),
57
+ expression: SQL.jsonExtract(SQL.column('organizations', 'meta'), '$.value.tags'),
58
58
  type: SQLValueType.JSONArray,
59
59
  nullable: false,
60
60
  }),
@@ -80,7 +80,7 @@ export const organizationFilterCompilers: SQLFilterDefinitions = {
80
80
  {
81
81
  ...baseSQLFilterCompilers,
82
82
  reviewedAt: createColumnFilter({
83
- expression: SQL.jsonValue(
83
+ expression: SQL.jsonExtract(
84
84
  SQL.column('organization_registration_periods', 'setupSteps'),
85
85
  `$.value.steps.${setupStep}.review.date`,
86
86
  ),
@@ -140,7 +140,7 @@ export const organizationFilterCompilers: SQLFilterDefinitions = {
140
140
  {
141
141
  ...baseSQLFilterCompilers,
142
142
  type: createColumnFilter({
143
- expression: SQL.jsonValue(SQL.column('meta'), '$.value.type'),
143
+ expression: SQL.jsonExtract(SQL.column('meta'), '$.value.type'),
144
144
  type: SQLValueType.JSONString,
145
145
  nullable: false,
146
146
  }),
@@ -181,7 +181,7 @@ export const organizationFilterCompilers: SQLFilterDefinitions = {
181
181
  nullable: false,
182
182
  }),
183
183
  email: createColumnFilter({
184
- expression: SQL.jsonValue(SQL.column('details'), '$.value.email'),
184
+ expression: SQL.jsonExtract(SQL.column('details'), '$.value.email'),
185
185
  type: SQLValueType.JSONString,
186
186
  nullable: true,
187
187
  }),
@@ -199,7 +199,7 @@ export const organizationFilterCompilers: SQLFilterDefinitions = {
199
199
  .join(
200
200
  SQL.join(
201
201
  SQL.jsonTable(
202
- SQL.jsonValue(SQL.column('innerOrganizations', 'meta'), '$.value.companies'),
202
+ SQL.jsonExtract(SQL.column('innerOrganizations', 'meta'), '$.value.companies'),
203
203
  'companies',
204
204
  )
205
205
  .addColumn(
@@ -1,4 +1,4 @@
1
- import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLCast, SQLConcat, SQLJsonUnquote, SQLFilterDefinitions, SQLValueType, SQLScalar } from '@stamhoofd/sql';
1
+ import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLCast, SQLConcat, SQLFilterDefinitions, SQLJsonUnquote, SQLScalar, SQLValueType } from '@stamhoofd/sql';
2
2
  import { balanceItemPaymentsCompilers } from './balance-item-payments';
3
3
 
4
4
  /**
@@ -59,26 +59,26 @@ export const paymentFilterCompilers: SQLFilterDefinitions = {
59
59
  customer: {
60
60
  ...baseSQLFilterCompilers,
61
61
  email: createColumnFilter({
62
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.email'),
62
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.email'),
63
63
  type: SQLValueType.JSONString,
64
64
  nullable: true,
65
65
  }),
66
66
  firstName: createColumnFilter({
67
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.firstName'),
67
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.firstName'),
68
68
  type: SQLValueType.JSONString,
69
69
  nullable: true,
70
70
  }),
71
71
  lastName: createColumnFilter({
72
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.lastName'),
72
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.lastName'),
73
73
  type: SQLValueType.JSONString,
74
74
  nullable: true,
75
75
  }),
76
76
  name: createColumnFilter({
77
77
  expression: new SQLCast(
78
78
  new SQLConcat(
79
- new SQLJsonUnquote(SQL.jsonValue(SQL.column('customer'), '$.value.firstName')),
79
+ new SQLJsonUnquote(SQL.jsonExtract(SQL.column('customer'), '$.value.firstName')),
80
80
  new SQLScalar(' '),
81
- new SQLJsonUnquote(SQL.jsonValue(SQL.column('customer'), '$.value.lastName')),
81
+ new SQLJsonUnquote(SQL.jsonExtract(SQL.column('customer'), '$.value.lastName')),
82
82
  ),
83
83
  'CHAR',
84
84
  ),
@@ -88,22 +88,22 @@ export const paymentFilterCompilers: SQLFilterDefinitions = {
88
88
  company: {
89
89
  ...baseSQLFilterCompilers,
90
90
  name: createColumnFilter({
91
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.company.name'),
91
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.company.name'),
92
92
  type: SQLValueType.JSONString,
93
93
  nullable: true,
94
94
  }),
95
95
  VATNumber: createColumnFilter({
96
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.company.VATNumber'),
96
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.company.VATNumber'),
97
97
  type: SQLValueType.JSONString,
98
98
  nullable: true,
99
99
  }),
100
100
  companyNumber: createColumnFilter({
101
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.company.companyNumber'),
101
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.company.companyNumber'),
102
102
  type: SQLValueType.JSONString,
103
103
  nullable: true,
104
104
  }),
105
105
  administrationEmail: createColumnFilter({
106
- expression: SQL.jsonValue(SQL.column('customer'), '$.value.company.administrationEmail'),
106
+ expression: SQL.jsonExtract(SQL.column('customer'), '$.value.company.administrationEmail'),
107
107
  type: SQLValueType.JSONString,
108
108
  nullable: true,
109
109
  }),
@@ -1,12 +1,16 @@
1
- import { Group, Member, Registration } from '@stamhoofd/models';
1
+ import { Group, Member, Organization, Registration } from '@stamhoofd/models';
2
2
  import { baseSQLFilterCompilers, createColumnFilter, createJoinedRelationFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
3
- import { baseRegistrationFilterCompilers } from './base-registration-filter-compilers';
4
- import { memberFilterCompilers } from './members';
3
+ import { SQLTranslatedString } from '../helpers/SQLTranslatedString.js';
4
+ import { baseRegistrationFilterCompilers } from './base-registration-filter-compilers.js';
5
+ import { memberFilterCompilers } from './members.js';
6
+ import { organizationFilterCompilers } from './organizations.js';
5
7
 
6
8
  export const memberJoin = SQL.join(Member.table).where(SQL.column(Member.table, 'id'), SQL.column(Registration.table, 'memberId'));
7
9
 
8
10
  export const groupJoin = SQL.join(Group.table).where(SQL.column(Group.table, 'id'), SQL.column(Registration.table, 'groupId'));
9
11
 
12
+ export const organizationJoin = SQL.join(Organization.table).where(SQL.column(Organization.table, 'id'), SQL.column(Registration.table, 'organizationId'));
13
+
10
14
  export const registrationFilterCompilers: SQLFilterDefinitions = {
11
15
  ...baseSQLFilterCompilers,
12
16
  ...baseRegistrationFilterCompilers,
@@ -29,9 +33,9 @@ export const registrationFilterCompilers: SQLFilterDefinitions = {
29
33
  nullable: false,
30
34
  }),
31
35
  name: createColumnFilter({
32
- expression: SQL.jsonValue(SQL.column('groups', 'settings'), '$.value.name'),
33
- type: SQLValueType.JSONString,
34
- nullable: false,
36
+ expression: new SQLTranslatedString(SQL.column('groups', 'settings'), '$.value.name'),
37
+ type: SQLValueType.String,
38
+ nullable: true,
35
39
  }),
36
40
  status: createColumnFilter({
37
41
  expression: SQL.column('groups', 'status'),
@@ -50,4 +54,8 @@ export const registrationFilterCompilers: SQLFilterDefinitions = {
50
54
  }),
51
55
  },
52
56
  ),
57
+ organization: createJoinedRelationFilter(
58
+ organizationJoin,
59
+ organizationFilterCompilers,
60
+ ),
53
61
  };
@@ -0,0 +1,79 @@
1
+ import { DocumentTemplate } from '@stamhoofd/models';
2
+ import { SQL, SQLOrderBy, SQLOrderByDirection, SQLSortDefinitions } from '@stamhoofd/sql';
3
+ import { Formatter } from '@stamhoofd/utility';
4
+
5
+ export const documentTemplateSorters: SQLSortDefinitions<DocumentTemplate> = {
6
+ // WARNING! TEST NEW SORTERS THOROUGHLY!
7
+ // Try to avoid creating sorters on fields that er not 1:1 with the database, that often causes pagination issues if not thought through
8
+ // An example: sorting on 'name' is not a good idea, because it is a concatenation of two fields.
9
+ // You might be tempted to use ORDER BY firstName, lastName, but that will not work as expected and it needs to be ORDER BY CONCAT(firstName, ' ', lastName)
10
+ // Why? Because ORDER BY firstName, lastName produces a different order dan ORDER BY CONCAT(firstName, ' ', lastName) if there are multiple people with spaces in the first name
11
+ // And that again causes issues with pagination because the next query will append a filter of name > 'John Doe' - causing duplicate and/or skipped results
12
+ // What if you need mapping? simply map the sorters in the frontend: name -> firstname, lastname, age -> birthDay, etc.
13
+ id: {
14
+ getValue(a) {
15
+ return a.id;
16
+ },
17
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
18
+ return new SQLOrderBy({
19
+ column: SQL.column('id'),
20
+ direction,
21
+ });
22
+ },
23
+ },
24
+ name: {
25
+ getValue(a) {
26
+ return a.settings.name;
27
+ },
28
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
29
+ return new SQLOrderBy({
30
+ column: SQL.jsonExtract(SQL.column('settings'), '$.value.name'),
31
+ direction,
32
+ });
33
+ },
34
+ },
35
+ year: {
36
+ getValue(a) {
37
+ return a.year;
38
+ },
39
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
40
+ return new SQLOrderBy({
41
+ column: SQL.column('year'),
42
+ direction,
43
+ });
44
+ },
45
+ },
46
+ updatedAt: {
47
+ getValue(a) {
48
+ return Formatter.dateTimeIso(a.updatedAt);
49
+ },
50
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
51
+ return new SQLOrderBy({
52
+ column: SQL.column('updatedAt'),
53
+ direction,
54
+ });
55
+ },
56
+ },
57
+ createdAt: {
58
+ getValue(a) {
59
+ return Formatter.dateTimeIso(a.createdAt);
60
+ },
61
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
62
+ return new SQLOrderBy({
63
+ column: SQL.column('createdAt'),
64
+ direction,
65
+ });
66
+ },
67
+ },
68
+ status: {
69
+ getValue(a) {
70
+ return a.status;
71
+ },
72
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
73
+ return new SQLOrderBy({
74
+ column: SQL.column('status'),
75
+ direction,
76
+ });
77
+ },
78
+ },
79
+ };
@@ -27,7 +27,7 @@ export const documentSorters: SQLSortDefinitions<Document> = {
27
27
  },
28
28
  toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
29
29
  return new SQLOrderBy({
30
- column: SQL.jsonValue(SQL.column('data'), '$.value.description'),
30
+ column: SQL.jsonExtract(SQL.column('data'), '$.value.description'),
31
31
  direction,
32
32
  });
33
33
  },
@@ -22,6 +22,17 @@ export const memberSorters: SQLSortDefinitions<MemberWithRegistrations> = {
22
22
  });
23
23
  },
24
24
  },
25
+ memberNumber: {
26
+ getValue(a) {
27
+ return a.memberNumber;
28
+ },
29
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
30
+ return new SQLOrderBy({
31
+ column: SQL.column('memberNumber'),
32
+ direction,
33
+ });
34
+ },
35
+ },
25
36
  firstName: {
26
37
  getValue(a) {
27
38
  return a.firstName;
@@ -55,4 +66,15 @@ export const memberSorters: SQLSortDefinitions<MemberWithRegistrations> = {
55
66
  });
56
67
  },
57
68
  },
69
+ createdAt: {
70
+ getValue(a) {
71
+ return a.createdAt;
72
+ },
73
+ toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
74
+ return new SQLOrderBy({
75
+ column: SQL.column('createdAt'),
76
+ direction,
77
+ });
78
+ },
79
+ },
58
80
  };