@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamhoofd/backend",
3
- "version": "2.44.0",
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.44.0",
40
- "@stamhoofd/backend-middleware": "2.44.0",
41
- "@stamhoofd/email": "2.44.0",
42
- "@stamhoofd/models": "2.44.0",
43
- "@stamhoofd/queues": "2.44.0",
44
- "@stamhoofd/sql": "2.44.0",
45
- "@stamhoofd/structures": "2.44.0",
46
- "@stamhoofd/utility": "2.44.0",
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": "1168aea7895e1aba48cd3123b09fc0b09a2b336f"
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
- // 'startDate': createSQLColumnFilterCompiler('startDate'),
9
- // 'endDate': createSQLColumnFilterCompiler('endDate'),
10
- // 'groupIds': createSQLExpressionFilterCompiler(
11
- // SQL.jsonValue(SQL.column('meta'), '$.value.groups[*].id'),
12
- // { isJSONValue: true, isJSONObject: true },
13
- // ),
14
- // 'defaultAgeGroupIds': createSQLExpressionFilterCompiler(
15
- // SQL.jsonValue(SQL.column('meta'), '$.value.defaultAgeGroupIds'),
16
- // { isJSONValue: true, isJSONObject: true },
17
- // ),
18
- // 'organizationTagIds': createSQLExpressionFilterCompiler(
19
- // SQL.jsonValue(SQL.column('meta'), '$.value.organizationTagIds'),
20
- // { isJSONValue: true, isJSONObject: true },
21
- // ),
22
- // 'meta.visible': createSQLExpressionFilterCompiler(
23
- // SQL.jsonValue(SQL.column('meta'), '$.value.visible'),
24
- // { isJSONValue: true, type: SQLValueType.JSONBoolean },
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.number;
15
+ return Formatter.dateTimeIso(a.createdAt);
17
16
  },
18
17
  toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
19
18
  return new SQLOrderBy({
20
- column: SQL.column('number'),
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
- createdAt: {
35
+ number: {
37
36
  getValue(a) {
38
- return Formatter.dateTimeIso(a.createdAt);
37
+ return a.number;
39
38
  },
40
39
  toSQL: (direction: SQLOrderByDirection): SQLOrderBy => {
41
40
  return new SQLOrderBy({
42
- column: SQL.column('createdAt'),
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
  };