@stamhoofd/backend 2.44.0 → 2.45.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/package.json +10 -10
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +8 -1
- package/src/seeds/1728928973-balance-item-pending.ts +11 -0
- package/src/seeds/1728928974-update-cached-outstanding-balance-from-items.ts +40 -0
- package/src/sql-filters/orders.ts +27 -20
- package/src/sql-sorters/orders.ts +90 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stamhoofd/backend",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.45.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"@simonbackx/simple-encoding": "2.15.1",
|
|
37
37
|
"@simonbackx/simple-endpoints": "1.14.0",
|
|
38
38
|
"@simonbackx/simple-logging": "^1.0.1",
|
|
39
|
-
"@stamhoofd/backend-i18n": "2.
|
|
40
|
-
"@stamhoofd/backend-middleware": "2.
|
|
41
|
-
"@stamhoofd/email": "2.
|
|
42
|
-
"@stamhoofd/models": "2.
|
|
43
|
-
"@stamhoofd/queues": "2.
|
|
44
|
-
"@stamhoofd/sql": "2.
|
|
45
|
-
"@stamhoofd/structures": "2.
|
|
46
|
-
"@stamhoofd/utility": "2.
|
|
39
|
+
"@stamhoofd/backend-i18n": "2.45.0",
|
|
40
|
+
"@stamhoofd/backend-middleware": "2.45.0",
|
|
41
|
+
"@stamhoofd/email": "2.45.0",
|
|
42
|
+
"@stamhoofd/models": "2.45.0",
|
|
43
|
+
"@stamhoofd/queues": "2.45.0",
|
|
44
|
+
"@stamhoofd/sql": "2.45.0",
|
|
45
|
+
"@stamhoofd/structures": "2.45.0",
|
|
46
|
+
"@stamhoofd/utility": "2.45.0",
|
|
47
47
|
"archiver": "^7.0.1",
|
|
48
48
|
"aws-sdk": "^2.885.0",
|
|
49
49
|
"axios": "1.6.8",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"postmark": "^4.0.5",
|
|
61
61
|
"stripe": "^16.6.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "c61562d189e2486d7669bd2bac5f3dca1804dc2c"
|
|
64
64
|
}
|
|
@@ -3,7 +3,7 @@ import { GroupPrivateSettings, Group as GroupStruct, GroupType, OrganizationRegi
|
|
|
3
3
|
|
|
4
4
|
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
5
5
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
|
-
import { Group, Member, Organization, OrganizationRegistrationPeriod, Platform, RegistrationPeriod } from '@stamhoofd/models';
|
|
6
|
+
import { Group, Member, Organization, OrganizationRegistrationPeriod, Platform, RegistrationPeriod, SetupStepUpdater } from '@stamhoofd/models';
|
|
7
7
|
import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures';
|
|
8
8
|
import { Context } from '../../../../helpers/Context';
|
|
9
9
|
|
|
@@ -166,10 +166,12 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
166
166
|
// #endregion
|
|
167
167
|
|
|
168
168
|
await organizationPeriod.save();
|
|
169
|
+
let shouldUpdateSetupSteps = false;
|
|
169
170
|
|
|
170
171
|
// Check changes to groups
|
|
171
172
|
const deleteGroups = patch.groups.getDeletes();
|
|
172
173
|
if (deleteGroups.length > 0) {
|
|
174
|
+
shouldUpdateSetupSteps = true;
|
|
173
175
|
for (const id of deleteGroups) {
|
|
174
176
|
await PatchOrganizationRegistrationPeriodsEndpoint.deleteGroup(id);
|
|
175
177
|
deleteUnreachable = true;
|
|
@@ -177,6 +179,7 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
for (const groupPut of patch.groups.getPuts()) {
|
|
182
|
+
shouldUpdateSetupSteps = true;
|
|
180
183
|
await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(groupPut.put, organization.id, period, { allowedIds });
|
|
181
184
|
deleteUnreachable = true;
|
|
182
185
|
}
|
|
@@ -193,6 +196,10 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
193
196
|
await Group.deleteUnreachable(organization.id, organizationPeriod, groups);
|
|
194
197
|
}
|
|
195
198
|
|
|
199
|
+
if (shouldUpdateSetupSteps) {
|
|
200
|
+
SetupStepUpdater.updateForOrganization(organization).catch(console.error);
|
|
201
|
+
}
|
|
202
|
+
|
|
196
203
|
periods.push(organizationPeriod);
|
|
197
204
|
}
|
|
198
205
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
+
import { BalanceItem } from '@stamhoofd/models';
|
|
3
|
+
|
|
4
|
+
export default new Migration(async () => {
|
|
5
|
+
if (STAMHOOFD.environment == 'test') {
|
|
6
|
+
console.log('skipped in tests');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
await BalanceItem.updatePricePending('all');
|
|
11
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
+
import { logger } from '@simonbackx/simple-logging';
|
|
3
|
+
import { BalanceItem } from '@stamhoofd/models';
|
|
4
|
+
|
|
5
|
+
export default new Migration(async () => {
|
|
6
|
+
if (STAMHOOFD.environment == 'test') {
|
|
7
|
+
console.log('skipped in tests');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
process.stdout.write('\n');
|
|
12
|
+
let c = 0;
|
|
13
|
+
let id: string = '';
|
|
14
|
+
|
|
15
|
+
await logger.setContext({ tags: ['silent-seed', 'seed'] }, async () => {
|
|
16
|
+
while (true) {
|
|
17
|
+
const items = await BalanceItem.where({
|
|
18
|
+
id: {
|
|
19
|
+
value: id,
|
|
20
|
+
sign: '>',
|
|
21
|
+
},
|
|
22
|
+
}, { limit: 1000, sort: ['id'] });
|
|
23
|
+
|
|
24
|
+
await BalanceItem.updateOutstanding(items);
|
|
25
|
+
|
|
26
|
+
c += items.length;
|
|
27
|
+
process.stdout.write('.');
|
|
28
|
+
|
|
29
|
+
if (items.length < 1000) {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
id = items[items.length - 1].id;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log('Updated outstanding balance for ' + c + ' items');
|
|
37
|
+
|
|
38
|
+
// Do something here
|
|
39
|
+
return Promise.resolve();
|
|
40
|
+
});
|
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
import { baseSQLFilterCompilers, createSQLColumnFilterCompiler, SQLFilterDefinitions } from '@stamhoofd/sql';
|
|
1
|
+
import { baseSQLFilterCompilers, createSQLColumnFilterCompiler, createSQLExpressionFilterCompiler, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const orderFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
-
id: createSQLColumnFilterCompiler('id'),
|
|
6
5
|
organizationId: createSQLColumnFilterCompiler('organizationId'),
|
|
6
|
+
id: createSQLColumnFilterCompiler('id'),
|
|
7
7
|
number: createSQLColumnFilterCompiler('number'),
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
8
|
+
status: createSQLColumnFilterCompiler('status'),
|
|
9
|
+
paymentMethod: createSQLExpressionFilterCompiler(
|
|
10
|
+
SQL.jsonValue(SQL.column('data'), '$.value.paymentMethod'),
|
|
11
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
12
|
+
),
|
|
13
|
+
checkoutMethod: createSQLExpressionFilterCompiler(
|
|
14
|
+
SQL.jsonValue(SQL.column('data'), '$.value.checkoutMethod.type'),
|
|
15
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
16
|
+
),
|
|
17
|
+
timeSlotDate: createSQLExpressionFilterCompiler(
|
|
18
|
+
SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.date'),
|
|
19
|
+
// todo: type?
|
|
20
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
21
|
+
),
|
|
22
|
+
timeSlotTime: createSQLExpressionFilterCompiler(
|
|
23
|
+
SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.endTime'),
|
|
24
|
+
// todo: type?
|
|
25
|
+
{ isJSONValue: true, type: SQLValueType.JSONString },
|
|
26
|
+
),
|
|
27
|
+
validAt: createSQLColumnFilterCompiler('validAt'),
|
|
28
|
+
totalPrice: createSQLExpressionFilterCompiler(
|
|
29
|
+
SQL.jsonValue(SQL.column('data'), '$.value.totalPrice'),
|
|
30
|
+
// todo: type?
|
|
31
|
+
{ isJSONValue: true },
|
|
32
|
+
),
|
|
26
33
|
};
|
|
@@ -10,14 +10,13 @@ export const orderSorters: SQLSortDefinitions<Order> = {
|
|
|
10
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
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
12
|
// What if you need mapping? simply map the sorters in the frontend: name -> firstname, lastname, age -> birthDay, etc.
|
|
13
|
-
|
|
14
|
-
number: {
|
|
13
|
+
createdAt: {
|
|
15
14
|
getValue(a) {
|
|
16
|
-
return a.
|
|
15
|
+
return Formatter.dateTimeIso(a.createdAt);
|
|
17
16
|
},
|
|
18
17
|
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
19
18
|
return new SQLOrderBy({
|
|
20
|
-
column: SQL.column('
|
|
19
|
+
column: SQL.column('createdAt'),
|
|
21
20
|
direction,
|
|
22
21
|
});
|
|
23
22
|
},
|
|
@@ -33,15 +32,99 @@ export const orderSorters: SQLSortDefinitions<Order> = {
|
|
|
33
32
|
});
|
|
34
33
|
},
|
|
35
34
|
},
|
|
36
|
-
|
|
35
|
+
number: {
|
|
37
36
|
getValue(a) {
|
|
38
|
-
return
|
|
37
|
+
return a.number;
|
|
39
38
|
},
|
|
40
39
|
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
41
40
|
return new SQLOrderBy({
|
|
42
|
-
column: SQL.column('
|
|
41
|
+
column: SQL.column('number'),
|
|
42
|
+
direction,
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
status: {
|
|
47
|
+
getValue(a) {
|
|
48
|
+
return a.status;
|
|
49
|
+
},
|
|
50
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
51
|
+
return new SQLOrderBy({
|
|
52
|
+
column: SQL.column('status'),
|
|
53
|
+
direction,
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
paymentMethod: {
|
|
58
|
+
getValue(a) {
|
|
59
|
+
return a.data.paymentMethod;
|
|
60
|
+
},
|
|
61
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
62
|
+
return new SQLOrderBy({
|
|
63
|
+
column: SQL.jsonValue(SQL.column('data'), '$.value.paymentMethod'),
|
|
64
|
+
direction,
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
checkoutMethod: {
|
|
69
|
+
getValue(a) {
|
|
70
|
+
return a.data.checkoutMethod?.type;
|
|
71
|
+
},
|
|
72
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
73
|
+
return new SQLOrderBy({
|
|
74
|
+
column: SQL.jsonValue(SQL.column('data'), '$.value.checkoutMethod.type'),
|
|
75
|
+
direction,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
timeSlotDate: {
|
|
80
|
+
getValue(a) {
|
|
81
|
+
return a.data.timeSlot?.date.getTime();
|
|
82
|
+
},
|
|
83
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
84
|
+
return new SQLOrderBy({
|
|
85
|
+
column: SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.date'),
|
|
86
|
+
direction,
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
timeSlotTime: {
|
|
91
|
+
getValue(a) {
|
|
92
|
+
return a.data.timeSlot?.endTime;
|
|
93
|
+
},
|
|
94
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
95
|
+
return new SQLOrderBy({
|
|
96
|
+
column: SQL.jsonValue(SQL.column('data'), '$.value.timeSlot.endTime'),
|
|
97
|
+
direction,
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
validAt: {
|
|
102
|
+
getValue(a) {
|
|
103
|
+
return a.validAt?.getTime();
|
|
104
|
+
},
|
|
105
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
106
|
+
return new SQLOrderBy({
|
|
107
|
+
column: SQL.column('validAt'),
|
|
108
|
+
direction,
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
totalPrice: {
|
|
113
|
+
getValue(a) {
|
|
114
|
+
return a.data.totalPrice;
|
|
115
|
+
},
|
|
116
|
+
toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
|
|
117
|
+
return new SQLOrderBy({
|
|
118
|
+
column: SQL.jsonValue(SQL.column('data'), '$.value.totalPrice'),
|
|
43
119
|
direction,
|
|
44
120
|
});
|
|
45
121
|
},
|
|
46
122
|
},
|
|
123
|
+
// amount: {
|
|
124
|
+
// getValue: (order) => {
|
|
125
|
+
// return order.data.cart.items.reduce((acc, item) => {
|
|
126
|
+
// return acc + item.amount;
|
|
127
|
+
// }, 0);
|
|
128
|
+
// }
|
|
129
|
+
// }
|
|
47
130
|
};
|