@stamhoofd/models 2.63.0 → 2.65.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/dist/src/helpers/EmailBuilder.d.ts +6 -1
- package/dist/src/helpers/EmailBuilder.d.ts.map +1 -1
- package/dist/src/helpers/EmailBuilder.js +60 -20
- package/dist/src/helpers/EmailBuilder.js.map +1 -1
- package/dist/src/helpers/MemberMerger.d.ts.map +1 -1
- package/dist/src/helpers/MemberMerger.js +1 -2
- package/dist/src/helpers/MemberMerger.js.map +1 -1
- package/dist/src/migrations/1605262045-import-postcodes.d.ts +3 -3
- package/dist/src/migrations/1605262045-import-postcodes.js +10 -13
- package/dist/src/migrations/1734429094-registration-trial-until.sql +3 -0
- package/dist/src/migrations/1734429095-membership-trial-until.sql +2 -0
- package/dist/src/migrations/1734535120-registration-period-previous-period-id.sql +3 -0
- package/dist/src/migrations/1734535121-platform-previous-period-id.sql +3 -0
- package/dist/src/migrations/1734626607-cached-balance-amount-open.sql +2 -0
- package/dist/src/migrations/1734698906-cached-balance-amount-paid.sql +2 -0
- package/dist/src/migrations/1735573520-emails-email-type.sql +2 -0
- package/dist/src/migrations/1735573521-email-recipients-email-type.sql +4 -0
- package/dist/src/migrations/1735573522-emails-indexes.sql +3 -0
- package/dist/src/migrations/1735982691-cached-balance-email-reminder-counts.sql +4 -0
- package/dist/src/migrations/1735994471-default-email-templates.sql +5 -0
- package/dist/src/models/AuditLog.d.ts +2 -7
- package/dist/src/models/AuditLog.d.ts.map +1 -1
- package/dist/src/models/AuditLog.js +1 -15
- package/dist/src/models/AuditLog.js.map +1 -1
- package/dist/src/models/BalanceItem.d.ts +4 -13
- package/dist/src/models/BalanceItem.d.ts.map +1 -1
- package/dist/src/models/BalanceItem.js +21 -33
- package/dist/src/models/BalanceItem.js.map +1 -1
- package/dist/src/models/BalanceItemPayment.d.ts +3 -2
- package/dist/src/models/BalanceItemPayment.d.ts.map +1 -1
- package/dist/src/models/BalanceItemPayment.js +2 -1
- package/dist/src/models/BalanceItemPayment.js.map +1 -1
- package/dist/src/models/BuckarooPayment.d.ts +2 -2
- package/dist/src/models/BuckarooPayment.d.ts.map +1 -1
- package/dist/src/models/BuckarooPayment.js +2 -1
- package/dist/src/models/BuckarooPayment.js.map +1 -1
- package/dist/src/models/CachedBalance.d.ts +12 -10
- package/dist/src/models/CachedBalance.d.ts.map +1 -1
- package/dist/src/models/CachedBalance.js +122 -39
- package/dist/src/models/CachedBalance.js.map +1 -1
- package/dist/src/models/Document.d.ts +3 -3
- package/dist/src/models/Document.d.ts.map +1 -1
- package/dist/src/models/Document.js +2 -1
- package/dist/src/models/Document.js.map +1 -1
- package/dist/src/models/DocumentTemplate.d.ts +2 -2
- package/dist/src/models/DocumentTemplate.d.ts.map +1 -1
- package/dist/src/models/DocumentTemplate.js +38 -10
- package/dist/src/models/DocumentTemplate.js.map +1 -1
- package/dist/src/models/Email.d.ts +10 -4
- package/dist/src/models/Email.d.ts.map +1 -1
- package/dist/src/models/Email.js +68 -25
- package/dist/src/models/Email.js.map +1 -1
- package/dist/src/models/EmailRecipient.d.ts +14 -8
- package/dist/src/models/EmailRecipient.d.ts.map +1 -1
- package/dist/src/models/EmailRecipient.js +19 -14
- package/dist/src/models/EmailRecipient.js.map +1 -1
- package/dist/src/models/EmailTemplate.d.ts +2 -7
- package/dist/src/models/EmailTemplate.d.ts.map +1 -1
- package/dist/src/models/EmailTemplate.js +1 -15
- package/dist/src/models/EmailTemplate.js.map +1 -1
- package/dist/src/models/EmailVerificationCode.d.ts +2 -2
- package/dist/src/models/EmailVerificationCode.d.ts.map +1 -1
- package/dist/src/models/EmailVerificationCode.js +2 -1
- package/dist/src/models/EmailVerificationCode.js.map +1 -1
- package/dist/src/models/Event.d.ts +2 -2
- package/dist/src/models/Event.d.ts.map +1 -1
- package/dist/src/models/Event.js +2 -1
- package/dist/src/models/Event.js.map +1 -1
- package/dist/src/models/Group.d.ts +2 -7
- package/dist/src/models/Group.d.ts.map +1 -1
- package/dist/src/models/Group.js +1 -17
- package/dist/src/models/Group.js.map +1 -1
- package/dist/src/models/Image.d.ts +2 -2
- package/dist/src/models/Image.d.ts.map +1 -1
- package/dist/src/models/Image.js +2 -1
- package/dist/src/models/Image.js.map +1 -1
- package/dist/src/models/Member.d.ts +6 -9
- package/dist/src/models/Member.d.ts.map +1 -1
- package/dist/src/models/Member.js +3 -42
- package/dist/src/models/Member.js.map +1 -1
- package/dist/src/models/MemberPlatformMembership.d.ts +12 -8
- package/dist/src/models/MemberPlatformMembership.d.ts.map +1 -1
- package/dist/src/models/MemberPlatformMembership.js +80 -20
- package/dist/src/models/MemberPlatformMembership.js.map +1 -1
- package/dist/src/models/MemberResponsibilityRecord.d.ts +2 -7
- package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -1
- package/dist/src/models/MemberResponsibilityRecord.js +1 -15
- package/dist/src/models/MemberResponsibilityRecord.js.map +1 -1
- package/dist/src/models/MemberUser.d.ts +8 -0
- package/dist/src/models/MemberUser.d.ts.map +1 -0
- package/dist/src/models/MemberUser.js +26 -0
- package/dist/src/models/MemberUser.js.map +1 -0
- package/dist/src/models/MergedMember.d.ts +3 -3
- package/dist/src/models/MergedMember.d.ts.map +1 -1
- package/dist/src/models/MergedMember.js +3 -2
- package/dist/src/models/MergedMember.js.map +1 -1
- package/dist/src/models/MolliePayment.d.ts +2 -2
- package/dist/src/models/MolliePayment.d.ts.map +1 -1
- package/dist/src/models/MolliePayment.js +2 -1
- package/dist/src/models/MolliePayment.js.map +1 -1
- package/dist/src/models/MollieToken.d.ts +2 -2
- package/dist/src/models/MollieToken.d.ts.map +1 -1
- package/dist/src/models/MollieToken.js +2 -1
- package/dist/src/models/MollieToken.js.map +1 -1
- package/dist/src/models/OneTimeToken.d.ts +2 -2
- package/dist/src/models/OneTimeToken.d.ts.map +1 -1
- package/dist/src/models/OneTimeToken.js +2 -1
- package/dist/src/models/OneTimeToken.js.map +1 -1
- package/dist/src/models/Order.d.ts +3 -2
- package/dist/src/models/Order.d.ts.map +1 -1
- package/dist/src/models/Order.js +2 -1
- package/dist/src/models/Order.js.map +1 -1
- package/dist/src/models/Organization.d.ts +2 -2
- package/dist/src/models/Organization.d.ts.map +1 -1
- package/dist/src/models/Organization.js +2 -1
- package/dist/src/models/Organization.js.map +1 -1
- package/dist/src/models/OrganizationRegistrationPeriod.d.ts +2 -2
- package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/OrganizationRegistrationPeriod.js +2 -1
- package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -1
- package/dist/src/models/PasswordToken.d.ts +3 -2
- package/dist/src/models/PasswordToken.d.ts.map +1 -1
- package/dist/src/models/PasswordToken.js +2 -1
- package/dist/src/models/PasswordToken.js.map +1 -1
- package/dist/src/models/PayconiqPayment.d.ts +2 -2
- package/dist/src/models/PayconiqPayment.d.ts.map +1 -1
- package/dist/src/models/PayconiqPayment.js +2 -1
- package/dist/src/models/PayconiqPayment.js.map +1 -1
- package/dist/src/models/Payment.d.ts +2 -7
- package/dist/src/models/Payment.d.ts.map +1 -1
- package/dist/src/models/Payment.js +1 -15
- package/dist/src/models/Payment.js.map +1 -1
- package/dist/src/models/Platform.d.ts +5 -3
- package/dist/src/models/Platform.d.ts.map +1 -1
- package/dist/src/models/Platform.js +11 -2
- package/dist/src/models/Platform.js.map +1 -1
- package/dist/src/models/RegisterCode.d.ts +2 -2
- package/dist/src/models/RegisterCode.d.ts.map +1 -1
- package/dist/src/models/RegisterCode.js +2 -1
- package/dist/src/models/RegisterCode.js.map +1 -1
- package/dist/src/models/Registration.d.ts +20 -7
- package/dist/src/models/Registration.d.ts.map +1 -1
- package/dist/src/models/Registration.js +25 -61
- package/dist/src/models/Registration.js.map +1 -1
- package/dist/src/models/RegistrationPeriod.d.ts +4 -2
- package/dist/src/models/RegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/RegistrationPeriod.js +23 -1
- package/dist/src/models/RegistrationPeriod.js.map +1 -1
- package/dist/src/models/STCredit.d.ts +2 -2
- package/dist/src/models/STCredit.d.ts.map +1 -1
- package/dist/src/models/STCredit.js +2 -1
- package/dist/src/models/STCredit.js.map +1 -1
- package/dist/src/models/STInvoice.d.ts +3 -2
- package/dist/src/models/STInvoice.d.ts.map +1 -1
- package/dist/src/models/STInvoice.js +2 -1
- package/dist/src/models/STInvoice.js.map +1 -1
- package/dist/src/models/STPackage.d.ts +2 -2
- package/dist/src/models/STPackage.d.ts.map +1 -1
- package/dist/src/models/STPackage.js +2 -1
- package/dist/src/models/STPackage.js.map +1 -1
- package/dist/src/models/STPendingInvoice.d.ts +3 -2
- package/dist/src/models/STPendingInvoice.d.ts.map +1 -1
- package/dist/src/models/STPendingInvoice.js +2 -1
- package/dist/src/models/STPendingInvoice.js.map +1 -1
- package/dist/src/models/StripeAccount.d.ts +2 -2
- package/dist/src/models/StripeAccount.d.ts.map +1 -1
- package/dist/src/models/StripeAccount.js +2 -1
- package/dist/src/models/StripeAccount.js.map +1 -1
- package/dist/src/models/StripeCheckoutSession.d.ts +2 -2
- package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -1
- package/dist/src/models/StripeCheckoutSession.js +2 -1
- package/dist/src/models/StripeCheckoutSession.js.map +1 -1
- package/dist/src/models/StripePaymentIntent.d.ts +2 -2
- package/dist/src/models/StripePaymentIntent.d.ts.map +1 -1
- package/dist/src/models/StripePaymentIntent.js +2 -1
- package/dist/src/models/StripePaymentIntent.js.map +1 -1
- package/dist/src/models/Ticket.d.ts +3 -2
- package/dist/src/models/Ticket.d.ts.map +1 -1
- package/dist/src/models/Ticket.js +2 -1
- package/dist/src/models/Ticket.js.map +1 -1
- package/dist/src/models/Token.d.ts +3 -2
- package/dist/src/models/Token.d.ts.map +1 -1
- package/dist/src/models/Token.js +2 -1
- package/dist/src/models/Token.js.map +1 -1
- package/dist/src/models/UsedRegisterCode.d.ts +2 -2
- package/dist/src/models/UsedRegisterCode.d.ts.map +1 -1
- package/dist/src/models/UsedRegisterCode.js +2 -1
- package/dist/src/models/UsedRegisterCode.js.map +1 -1
- package/dist/src/models/User.d.ts +7 -2
- package/dist/src/models/User.d.ts.map +1 -1
- package/dist/src/models/User.js +27 -4
- package/dist/src/models/User.js.map +1 -1
- package/dist/src/models/UserPermissions.d.ts +3 -2
- package/dist/src/models/UserPermissions.d.ts.map +1 -1
- package/dist/src/models/UserPermissions.js +2 -1
- package/dist/src/models/UserPermissions.js.map +1 -1
- package/dist/src/models/Webshop.d.ts +3 -2
- package/dist/src/models/Webshop.d.ts.map +1 -1
- package/dist/src/models/Webshop.js +2 -1
- package/dist/src/models/Webshop.js.map +1 -1
- package/dist/src/models/WebshopDiscountCode.d.ts +2 -2
- package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -1
- package/dist/src/models/WebshopDiscountCode.js +2 -1
- package/dist/src/models/WebshopDiscountCode.js.map +1 -1
- package/dist/src/models/addresses/City.d.ts +3 -2
- package/dist/src/models/addresses/City.d.ts.map +1 -1
- package/dist/src/models/addresses/City.js +2 -1
- package/dist/src/models/addresses/City.js.map +1 -1
- package/dist/src/models/addresses/PostalCode.d.ts +3 -2
- package/dist/src/models/addresses/PostalCode.d.ts.map +1 -1
- package/dist/src/models/addresses/PostalCode.js +2 -1
- package/dist/src/models/addresses/PostalCode.js.map +1 -1
- package/dist/src/models/addresses/Province.d.ts +2 -2
- package/dist/src/models/addresses/Province.d.ts.map +1 -1
- package/dist/src/models/addresses/Province.js +2 -1
- package/dist/src/models/addresses/Province.js.map +1 -1
- package/dist/src/models/addresses/Street.d.ts +3 -2
- package/dist/src/models/addresses/Street.d.ts.map +1 -1
- package/dist/src/models/addresses/Street.js +2 -1
- package/dist/src/models/addresses/Street.js.map +1 -1
- package/dist/src/models/index.d.ts +1 -0
- package/dist/src/models/index.d.ts.map +1 -1
- package/dist/src/models/index.js +1 -0
- package/dist/src/models/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/helpers/EmailBuilder.ts +82 -27
- package/src/helpers/MemberMerger.ts +2 -3
- package/src/migrations/1605262045-import-postcodes.ts +6 -9
- package/src/migrations/1734429094-registration-trial-until.sql +3 -0
- package/src/migrations/1734429095-membership-trial-until.sql +2 -0
- package/src/migrations/1734535120-registration-period-previous-period-id.sql +3 -0
- package/src/migrations/1734535121-platform-previous-period-id.sql +3 -0
- package/src/migrations/1734626607-cached-balance-amount-open.sql +2 -0
- package/src/migrations/1734698906-cached-balance-amount-paid.sql +2 -0
- package/src/migrations/1735573520-emails-email-type.sql +2 -0
- package/src/migrations/1735573521-email-recipients-email-type.sql +4 -0
- package/src/migrations/1735573522-emails-indexes.sql +3 -0
- package/src/migrations/1735982691-cached-balance-email-reminder-counts.sql +4 -0
- package/src/migrations/1735994471-default-email-templates.sql +5 -0
- package/src/models/AuditLog.ts +3 -21
- package/src/models/BalanceItem.ts +30 -46
- package/src/models/BalanceItemPayment.ts +3 -2
- package/src/models/BuckarooPayment.ts +3 -2
- package/src/models/CachedBalance.ts +166 -46
- package/src/models/Document.ts +4 -3
- package/src/models/DocumentTemplate.ts +43 -12
- package/src/models/Email.ts +80 -32
- package/src/models/EmailRecipient.ts +20 -20
- package/src/models/EmailTemplate.ts +3 -21
- package/src/models/EmailVerificationCode.ts +3 -2
- package/src/models/Event.ts +3 -2
- package/src/models/Group.ts +4 -23
- package/src/models/Image.ts +3 -2
- package/src/models/Member.ts +6 -52
- package/src/models/MemberPlatformMembership.ts +95 -26
- package/src/models/MemberResponsibilityRecord.ts +3 -21
- package/src/models/MemberUser.ts +18 -0
- package/src/models/MergedMember.ts +4 -3
- package/src/models/MolliePayment.ts +3 -2
- package/src/models/MollieToken.ts +3 -2
- package/src/models/OneTimeToken.ts +3 -2
- package/src/models/Order.ts +3 -2
- package/src/models/Organization.ts +3 -2
- package/src/models/OrganizationRegistrationPeriod.ts +3 -2
- package/src/models/PasswordToken.ts +3 -2
- package/src/models/PayconiqPayment.ts +3 -2
- package/src/models/Payment.ts +3 -21
- package/src/models/Platform.ts +13 -4
- package/src/models/RegisterCode.ts +3 -2
- package/src/models/Registration.ts +24 -68
- package/src/models/RegistrationPeriod.ts +30 -3
- package/src/models/STCredit.ts +3 -2
- package/src/models/STInvoice.ts +3 -2
- package/src/models/STPackage.ts +3 -2
- package/src/models/STPendingInvoice.ts +3 -2
- package/src/models/StripeAccount.ts +3 -2
- package/src/models/StripeCheckoutSession.ts +3 -2
- package/src/models/StripePaymentIntent.ts +3 -2
- package/src/models/Ticket.ts +3 -2
- package/src/models/Token.ts +3 -2
- package/src/models/UsedRegisterCode.ts +3 -2
- package/src/models/User.ts +31 -3
- package/src/models/UserPermissions.ts +3 -2
- package/src/models/Webshop.ts +3 -2
- package/src/models/WebshopDiscountCode.ts +3 -2
- package/src/models/addresses/City.ts +3 -2
- package/src/models/addresses/PostalCode.ts +3 -2
- package/src/models/addresses/Province.ts +3 -2
- package/src/models/addresses/Street.ts +3 -2
- package/src/models/index.ts +1 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Email, EmailAddress, EmailBuilder } from '@stamhoofd/email';
|
|
2
|
-
import { EmailTemplateType, OrganizationEmail, Recipient, Replacement } from '@stamhoofd/structures';
|
|
2
|
+
import { Platform as PlatformStruct, BalanceItem as BalanceItemStruct, EmailTemplateType, OrganizationEmail, ReceivableBalanceType, Recipient, Replacement } from '@stamhoofd/structures';
|
|
3
3
|
import { Formatter } from '@stamhoofd/utility';
|
|
4
4
|
|
|
5
5
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
|
-
import { EmailTemplate, Group, Organization, Platform, User, Webshop } from '../models';
|
|
6
|
+
import { CachedBalance, EmailTemplate, Group, Organization, Platform, User, Webshop } from '../models';
|
|
7
7
|
import { I18n } from '@stamhoofd/backend-i18n';
|
|
8
8
|
|
|
9
9
|
export type EmailTemplateOptions = {
|
|
@@ -238,7 +238,7 @@ export function replaceText(text: string, replacements: Replacement[]) {
|
|
|
238
238
|
* @param organization defines replacements and unsubsribe behaviour
|
|
239
239
|
*/
|
|
240
240
|
export async function getEmailBuilder(organization: Organization | null, email: EmailBuilderOptions) {
|
|
241
|
-
const platform = await Platform.
|
|
241
|
+
const platform = await Platform.getSharedPrivateStruct();
|
|
242
242
|
// Update recipients
|
|
243
243
|
const cleaned: Recipient[] = [];
|
|
244
244
|
for (const recipient of email.recipients) {
|
|
@@ -305,38 +305,21 @@ export async function getEmailBuilder(organization: Organization | null, email:
|
|
|
305
305
|
}
|
|
306
306
|
email.recipients = cleaned;
|
|
307
307
|
|
|
308
|
+
const fromAddress = Email.parseEmailStr(email.from)[0];
|
|
309
|
+
|
|
308
310
|
// Update recipients
|
|
309
311
|
for (const recipient of email.recipients) {
|
|
310
312
|
recipient.replacements = recipient.replacements.slice();
|
|
311
313
|
|
|
312
|
-
// Default signInUrl
|
|
313
|
-
let signInUrl = 'https://' + (organization && STAMHOOFD.userMode === 'organization' ? organization.getHost() : STAMHOOFD.domains.dashboard) + '/login?email=' + encodeURIComponent(recipient.email);
|
|
314
|
-
|
|
315
|
-
const recipientUser = await User.getForAuthentication(organization?.id ?? null, recipient.email);
|
|
316
|
-
if (!recipientUser) {
|
|
317
|
-
// We can create a special token
|
|
318
|
-
signInUrl = 'https://' + (organization && STAMHOOFD.userMode === 'organization' ? organization.getHost() : STAMHOOFD.domains.dashboard) + '/account-aanmaken?email=' + encodeURIComponent(recipient.email);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
recipient.replacements.push(Replacement.create({
|
|
322
|
-
token: 'signInUrl',
|
|
323
|
-
value: signInUrl,
|
|
324
|
-
}));
|
|
325
|
-
|
|
326
314
|
if (email.defaultReplacements) {
|
|
327
315
|
recipient.replacements.push(...email.defaultReplacements);
|
|
328
316
|
}
|
|
329
317
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Defaults
|
|
338
|
-
const extra = platform.config.getEmailReplacements();
|
|
339
|
-
recipient.replacements.push(...extra);
|
|
318
|
+
await fillRecipientReplacements(recipient, {
|
|
319
|
+
organization,
|
|
320
|
+
platform,
|
|
321
|
+
fromAddress,
|
|
322
|
+
});
|
|
340
323
|
}
|
|
341
324
|
|
|
342
325
|
const queue = email.recipients.slice();
|
|
@@ -380,3 +363,75 @@ export async function getEmailBuilder(organization: Organization | null, email:
|
|
|
380
363
|
};
|
|
381
364
|
return builder;
|
|
382
365
|
}
|
|
366
|
+
|
|
367
|
+
export async function fillRecipientReplacements(recipient: Recipient, options: {
|
|
368
|
+
organization: Organization | null;
|
|
369
|
+
platform?: PlatformStruct;
|
|
370
|
+
fromAddress: string | null;
|
|
371
|
+
}) {
|
|
372
|
+
if (!options.platform) {
|
|
373
|
+
options.platform = await Platform.getSharedPrivateStruct();
|
|
374
|
+
}
|
|
375
|
+
const { organization, platform, fromAddress } = options;
|
|
376
|
+
recipient.replacements = recipient.replacements.slice();
|
|
377
|
+
|
|
378
|
+
// Default signInUrl
|
|
379
|
+
let signInUrl = 'https://' + (organization && STAMHOOFD.userMode === 'organization' ? organization.getHost() : STAMHOOFD.domains.dashboard) + '/login?email=' + encodeURIComponent(recipient.email);
|
|
380
|
+
|
|
381
|
+
const recipientUser = await User.getForAuthentication(organization?.id ?? null, recipient.email, { allowWithoutAccount: true });
|
|
382
|
+
if (!recipientUser || !recipientUser.hasAccount()) {
|
|
383
|
+
// We can create a special token
|
|
384
|
+
signInUrl = 'https://' + (organization && STAMHOOFD.userMode === 'organization' ? organization.getHost() : STAMHOOFD.domains.dashboard) + '/account-aanmaken?email=' + encodeURIComponent(recipient.email);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
recipient.replacements.push(Replacement.create({
|
|
388
|
+
token: 'signInUrl',
|
|
389
|
+
value: signInUrl,
|
|
390
|
+
}));
|
|
391
|
+
|
|
392
|
+
recipient.replacements.push(
|
|
393
|
+
Replacement.create({
|
|
394
|
+
token: 'loginDetails',
|
|
395
|
+
value: '',
|
|
396
|
+
html: recipientUser && recipientUser.hasAccount() ? `<p class="description"><em>Je kan op het ledenportaal inloggen met <strong>${Formatter.escapeHtml(recipientUser.email)}</strong></em></p>` : `<p class="description"><em>Je kan op het ledenportaal een nieuw account aanmaken met het e-mailadres <strong>${Formatter.escapeHtml(recipient.email)}</strong>, dan krijg je automatisch toegang tot alle bestaande gegevens.</em></p>`,
|
|
397
|
+
}),
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
// Load balance of this user
|
|
401
|
+
// todo: only if detected it is used
|
|
402
|
+
if (organization && recipientUser && !recipient.replacements.find(r => r.token === 'balanceTable')) {
|
|
403
|
+
const balanceItemModels = await CachedBalance.balanceForObjects(organization.id, [recipientUser.id], ReceivableBalanceType.user, true);
|
|
404
|
+
const balanceItems = balanceItemModels.map(i => i.getStructure());
|
|
405
|
+
|
|
406
|
+
// Get members
|
|
407
|
+
recipient.replacements.push(
|
|
408
|
+
Replacement.create({
|
|
409
|
+
token: 'outstandingBalance',
|
|
410
|
+
value: Formatter.price(balanceItems.reduce((sum, i) => sum + i.priceOpen, 0)),
|
|
411
|
+
}),
|
|
412
|
+
Replacement.create({
|
|
413
|
+
token: 'balanceTable',
|
|
414
|
+
value: '',
|
|
415
|
+
html: BalanceItemStruct.getDetailsHTMLTable(balanceItems),
|
|
416
|
+
}),
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (fromAddress) {
|
|
421
|
+
recipient.replacements.push(Replacement.create({
|
|
422
|
+
token: 'fromAddress',
|
|
423
|
+
value: fromAddress,
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
recipient.replacements.push(...recipient.getDefaultReplacements());
|
|
428
|
+
|
|
429
|
+
if (organization) {
|
|
430
|
+
const extra = organization.meta.getEmailReplacements(organization);
|
|
431
|
+
recipient.replacements.push(...extra);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Defaults
|
|
435
|
+
const extra = platform.config.getEmailReplacements();
|
|
436
|
+
recipient.replacements.push(...extra);
|
|
437
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SQL } from '@stamhoofd/sql';
|
|
1
|
+
import { QueryableModel, SQL } from '@stamhoofd/sql';
|
|
3
2
|
import {
|
|
4
3
|
Address,
|
|
5
4
|
BooleanStatus,
|
|
@@ -191,7 +190,7 @@ async function mergeMemberPlatformMemberships(base: Member, other: Member) {
|
|
|
191
190
|
await mergeModels(base, other, MemberPlatformMembership);
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
class ModelWithMemberId extends
|
|
193
|
+
class ModelWithMemberId extends QueryableModel {
|
|
195
194
|
memberId: string | null;
|
|
196
195
|
}
|
|
197
196
|
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
-
import {
|
|
3
|
-
import { StringCompare } from '@stamhoofd/utility';
|
|
4
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
1
|
+
import { column, Migration } from '@simonbackx/simple-database';
|
|
2
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
5
3
|
import { Country } from '@stamhoofd/structures';
|
|
4
|
+
import { StringCompare } from '@stamhoofd/utility';
|
|
6
5
|
import { City } from '../models/addresses/City';
|
|
7
6
|
import { PostalCode } from '../models/addresses/PostalCode';
|
|
8
7
|
import { Province } from '../models/addresses/Province';
|
|
9
8
|
|
|
10
|
-
export class Gemeente extends
|
|
9
|
+
export class Gemeente extends QueryableModel {
|
|
11
10
|
static table = 'gemeenten';
|
|
12
11
|
|
|
13
12
|
@column({
|
|
14
|
-
primary: true, type: '
|
|
15
|
-
return value ?? uuidv4();
|
|
16
|
-
},
|
|
13
|
+
primary: true, type: 'integer',
|
|
17
14
|
})
|
|
18
|
-
id!:
|
|
15
|
+
id!: number;
|
|
19
16
|
|
|
20
17
|
@column({ type: 'string' })
|
|
21
18
|
postcode: string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
INSERT INTO `email_templates` (`id`, `subject`, `groupId`, `webshopId`, `organizationId`, `type`, `text`, `html`, `json`, `updatedAt`, `createdAt`) VALUES
|
|
2
|
+
('8aec66ec-a39c-4849-9ebf-973e489f8017', 'Jouw openstaand saldo bij {{organizationName}}', NULL, NULL, NULL, 'OrganizationBalanceIncreaseNotification', '{{greeting}}Jouw groep ({{objectName}}) heeft een nieuw openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het beheerdersportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het beheerdersportaal.\n\n \n \n \n \n Betalen via het beheerdersportaal\n \n \n \n \n\nTwijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het beheerdersportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.Vragen over je openstaand bedrag? Neem dan contact op met {{organizationName}} via {{fromAddress}}OverzichtDit is een momentopname van jullie huidige openstaande bedrag. Je kan op elk moment naar het beheerdersportaal gaan om de huidige status te bekijken en te betalen.{{balanceTable}}Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via deze knop — hierna zal je nooit meer een e-mail van ons ontvangen.Uitschrijven', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>Jouw openstaand saldo bij {{organizationName}}</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n}\n\n.email-style-inline-code {\n font-family: monospace;\n white-space: pre-wrap;\n display: inline-block;\n}\n\n.email-style-description-small {\n font-size: 14px;\n line-height: 1.5;\n font-weight: normal;\n color: var(--color-gray-4, #5e5e5e);\n font-variation-settings: \"opsz\" 19;\n}\n\n.email-style-title-list {\n font-size: 16px;\n line-height: 1.3;\n font-weight: 500;\n}\n.email-style-title-list + p {\n padding-top: 3px;\n}\n\n.email-style-title-prefix-list {\n font-size: 11px;\n line-height: 1.5;\n font-weight: bold;\n color: {{primaryColor}};\n text-transform: uppercase;\n margin-bottom: 3px;\n}\n.email-style-title-prefix-list.error {\n color: #f0153d;\n}\n\n.email-style-price-base, .email-style-discount-price, .email-style-discount-old-price, .email-style-price {\n font-size: 15px;\n line-height: 1.4;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n}\n.email-style-price-base.disabled, .disabled.email-style-discount-price, .disabled.email-style-discount-old-price, .disabled.email-style-price {\n opacity: 0.6;\n}\n.email-style-price-base.negative, .negative.email-style-discount-price, .negative.email-style-discount-old-price, .negative.email-style-price {\n color: #f0153d;\n}\n\n.email-style-price {\n font-weight: bold;\n color: {{primaryColor}};\n}\n\n.email-style-discount-old-price {\n text-decoration: line-through;\n color: var(--color-gray-4, #5e5e5e);\n}\n\n.email-style-discount-price {\n font-weight: bold;\n color: #ff4747;\n margin-left: 5px;\n}\n\n.pre-wrap {\n white-space: pre-wrap;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Jouw groep ({{objectName}}) heeft een nieuw openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het beheerdersportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><strong>Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het beheerdersportaal.</strong></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"paymentUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{paymentUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Betalen via het beheerdersportaal</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p class=\"description\" style=\"color: #5e5e5e;\"><em>Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het beheerdersportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><strong><em>Vragen over je openstaand bedrag</em></strong><em>? Neem dan contact op met </em>{{organizationName}} <em>via </em>{{fromAddress}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><hr style=\"height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;\"><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><h2 style=\"margin: 0; padding: 0;\">Overzicht</h2><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Dit is een momentopname van jullie huidige openstaande bedrag. Je kan op elk moment naar het beheerdersportaal gaan om de huidige status te bekijken en te betalen.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartVariableBlock\" data-id=\"balanceTable\">{{balanceTable}}</div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><em>Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via </em><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\"><em>deze knop</em></a><em> — hierna zal je nooit meer een e-mail van ons ontvangen.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\">Uitschrijven</a></p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Jouw groep (\", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"objectName\"}}, {\"text\": \") heeft een nieuw openstaand bedrag van \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"outstandingBalance\"}}, {\"text\": \" bij \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \". Je kan de betaling in orde brengen door naar het beheerdersportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het beheerdersportaal.\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"paymentUrl\"}, \"content\": [{\"text\": \"Betalen via het beheerdersportaal\", \"type\": \"text\"}]}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het beheerdersportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Vragen over je openstaand bedrag\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}, {\"type\": \"italic\"}]}, {\"text\": \"? Neem dan contact op met \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \" \", \"type\": \"text\"}, {\"text\": \"via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"fromAddress\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"horizontalRule\"}, {\"type\": \"paragraph\"}, {\"type\": \"heading\", \"attrs\": {\"level\": 2}, \"content\": [{\"text\": \"Overzicht\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Dit is een momentopname van jullie huidige openstaande bedrag. Je kan op elk moment naar het beheerdersportaal gaan om de huidige status te bekijken en te betalen.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartVariableBlock\", \"attrs\": {\"id\": \"balanceTable\"}}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"deze knop\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"text\": \" — hierna zal je nooit meer een e-mail van ons ontvangen.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"Uitschrijven\", \"type\": \"text\"}]}]}]}, \"version\": 354}', '2025-01-04 12:09:03', '2025-01-04 12:09:03'),
|
|
3
|
+
('01f3c594-43e1-45de-9ca9-e450befb4426', '[Herinnering] Openstaand bedrag te betalen aan {{organizationName}}', NULL, NULL, NULL, 'OrganizationBalanceReminder', '{{greeting}}Jouw groep ({{objectName}}) heeft nog steeds een openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het beheerdersportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het beheerdersportaal.\n\n \n \n \n \n Betalen via het beheerdersportaal\n \n \n \n \n\nTwijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het beheerdersportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.Vragen over je openstaand bedrag? Neem dan contact op met {{organizationName}} via {{fromAddress}}OverzichtDit is een momentopname van jullie huidige openstaande bedrag. Je kan op elk moment naar het beheerdersportaal gaan om de huidige status te bekijken en te betalen.{{balanceTable}}Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via deze knop — hierna zal je nooit meer een e-mail van ons ontvangen.Uitschrijven', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>[Herinnering] Openstaand bedrag te betalen aan {{organizationName}}</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n}\n\n.email-style-inline-code {\n font-family: monospace;\n white-space: pre-wrap;\n display: inline-block;\n}\n\n.email-style-description-small {\n font-size: 14px;\n line-height: 1.5;\n font-weight: normal;\n color: var(--color-gray-4, #5e5e5e);\n font-variation-settings: \"opsz\" 19;\n}\n\n.email-style-title-list {\n font-size: 16px;\n line-height: 1.3;\n font-weight: 500;\n}\n.email-style-title-list + p {\n padding-top: 3px;\n}\n\n.email-style-title-prefix-list {\n font-size: 11px;\n line-height: 1.5;\n font-weight: bold;\n color: {{primaryColor}};\n text-transform: uppercase;\n margin-bottom: 3px;\n}\n.email-style-title-prefix-list.error {\n color: #f0153d;\n}\n\n.email-style-price-base, .email-style-discount-price, .email-style-discount-old-price, .email-style-price {\n font-size: 15px;\n line-height: 1.4;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n}\n.email-style-price-base.disabled, .disabled.email-style-discount-price, .disabled.email-style-discount-old-price, .disabled.email-style-price {\n opacity: 0.6;\n}\n.email-style-price-base.negative, .negative.email-style-discount-price, .negative.email-style-discount-old-price, .negative.email-style-price {\n color: #f0153d;\n}\n\n.email-style-price {\n font-weight: bold;\n color: {{primaryColor}};\n}\n\n.email-style-discount-old-price {\n text-decoration: line-through;\n color: var(--color-gray-4, #5e5e5e);\n}\n\n.email-style-discount-price {\n font-weight: bold;\n color: #ff4747;\n margin-left: 5px;\n}\n\n.pre-wrap {\n white-space: pre-wrap;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Jouw groep ({{objectName}}) heeft nog steeds een openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het beheerdersportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><strong>Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het beheerdersportaal.</strong></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"paymentUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{paymentUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Betalen via het beheerdersportaal</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p class=\"description\" style=\"color: #5e5e5e;\"><em>Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het beheerdersportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><strong><em>Vragen over je openstaand bedrag</em></strong><em>? Neem dan contact op met </em>{{organizationName}} <em>via </em>{{fromAddress}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><hr style=\"height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;\"><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><h2 style=\"margin: 0; padding: 0;\">Overzicht</h2><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Dit is een momentopname van jullie huidige openstaande bedrag. Je kan op elk moment naar het beheerdersportaal gaan om de huidige status te bekijken en te betalen.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartVariableBlock\" data-id=\"balanceTable\">{{balanceTable}}</div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><em>Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via </em><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\"><em>deze knop</em></a><em> — hierna zal je nooit meer een e-mail van ons ontvangen.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\">Uitschrijven</a></p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Jouw groep (\", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"objectName\"}}, {\"text\": \") heeft nog steeds een openstaand bedrag van \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"outstandingBalance\"}}, {\"text\": \" bij \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \". Je kan de betaling in orde brengen door naar het beheerdersportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het beheerdersportaal.\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"paymentUrl\"}, \"content\": [{\"text\": \"Betalen via het beheerdersportaal\", \"type\": \"text\"}]}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het beheerdersportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Vragen over je openstaand bedrag\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}, {\"type\": \"italic\"}]}, {\"text\": \"? Neem dan contact op met \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \" \", \"type\": \"text\"}, {\"text\": \"via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"fromAddress\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"horizontalRule\"}, {\"type\": \"paragraph\"}, {\"type\": \"heading\", \"attrs\": {\"level\": 2}, \"content\": [{\"text\": \"Overzicht\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Dit is een momentopname van jullie huidige openstaande bedrag. Je kan op elk moment naar het beheerdersportaal gaan om de huidige status te bekijken en te betalen.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartVariableBlock\", \"attrs\": {\"id\": \"balanceTable\"}}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"deze knop\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"text\": \" — hierna zal je nooit meer een e-mail van ons ontvangen.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"Uitschrijven\", \"type\": \"text\"}]}]}]}, \"version\": 354}', '2025-01-04 12:09:03', '2025-01-04 12:09:03'),
|
|
4
|
+
('b313f990-1f86-4571-931e-e3a46999cbea', '[Herinnering] Openstaand bedrag te betalen aan {{organizationName}}', NULL, NULL, NULL, 'UserBalanceReminder', '{{greeting}}Je hebt een openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het ledenportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het ledenportaal.\n\n \n \n \n \n Betalen via het ledenportaal\n \n \n \n \n\nTwijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het ledenportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.Vragen over je openstaand bedrag? Neem dan contact op met {{organizationName}} via {{fromAddress}}OverzichtDit is een momentopname van je huidige openstaande bedrag. Je kan op elk moment naar het ledenportaal gaan om de huidige status te bekijken en te betalen.{{balanceTable}}Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via deze knop — hierna zal je nooit meer een e-mail van ons ontvangen.Uitschrijven', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>[Herinnering] Openstaand bedrag te betalen aan {{organizationName}}</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n}\n\n.email-style-inline-code {\n font-family: monospace;\n white-space: pre-wrap;\n display: inline-block;\n}\n\n.email-style-description-small {\n font-size: 14px;\n line-height: 1.5;\n font-weight: normal;\n color: var(--color-gray-4, #5e5e5e);\n font-variation-settings: \"opsz\" 19;\n}\n\n.email-style-title-list {\n font-size: 16px;\n line-height: 1.3;\n font-weight: 500;\n}\n.email-style-title-list + p {\n padding-top: 3px;\n}\n\n.email-style-title-prefix-list {\n font-size: 11px;\n line-height: 1.5;\n font-weight: bold;\n color: {{primaryColor}};\n text-transform: uppercase;\n margin-bottom: 3px;\n}\n.email-style-title-prefix-list.error {\n color: #f0153d;\n}\n\n.email-style-price-base, .email-style-discount-price, .email-style-discount-old-price, .email-style-price {\n font-size: 15px;\n line-height: 1.4;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n}\n.email-style-price-base.disabled, .disabled.email-style-discount-price, .disabled.email-style-discount-old-price, .disabled.email-style-price {\n opacity: 0.6;\n}\n.email-style-price-base.negative, .negative.email-style-discount-price, .negative.email-style-discount-old-price, .negative.email-style-price {\n color: #f0153d;\n}\n\n.email-style-price {\n font-weight: bold;\n color: {{primaryColor}};\n}\n\n.email-style-discount-old-price {\n text-decoration: line-through;\n color: var(--color-gray-4, #5e5e5e);\n}\n\n.email-style-discount-price {\n font-weight: bold;\n color: #ff4747;\n margin-left: 5px;\n}\n\n.pre-wrap {\n white-space: pre-wrap;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Je hebt een openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het ledenportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><strong>Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het ledenportaal.</strong></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"paymentUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{paymentUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Betalen via het ledenportaal</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p class=\"description\" style=\"color: #5e5e5e;\"><em>Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het ledenportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><strong><em>Vragen over je openstaand bedrag</em></strong><em>? Neem dan contact op met </em>{{organizationName}} <em>via </em>{{fromAddress}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><hr style=\"height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;\"><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><h2 style=\"margin: 0; padding: 0;\">Overzicht</h2><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Dit is een momentopname van je huidige openstaande bedrag. Je kan op elk moment naar het ledenportaal gaan om de huidige status te bekijken en te betalen.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartVariableBlock\" data-id=\"balanceTable\">{{balanceTable}}</div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><em>Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via </em><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\"><em>deze knop</em></a><em> — hierna zal je nooit meer een e-mail van ons ontvangen.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\">Uitschrijven</a></p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Je hebt een openstaand bedrag van \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"outstandingBalance\"}}, {\"text\": \" bij \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \". Je kan de betaling in orde brengen door naar het ledenportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het ledenportaal.\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"paymentUrl\"}, \"content\": [{\"text\": \"Betalen via het ledenportaal\", \"type\": \"text\"}]}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het ledenportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Vragen over je openstaand bedrag\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}, {\"type\": \"italic\"}]}, {\"text\": \"? Neem dan contact op met \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \" \", \"type\": \"text\"}, {\"text\": \"via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"fromAddress\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"horizontalRule\"}, {\"type\": \"paragraph\"}, {\"type\": \"heading\", \"attrs\": {\"level\": 2}, \"content\": [{\"text\": \"Overzicht\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Dit is een momentopname van je huidige openstaande bedrag. Je kan op elk moment naar het ledenportaal gaan om de huidige status te bekijken en te betalen.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartVariableBlock\", \"attrs\": {\"id\": \"balanceTable\"}}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"deze knop\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"text\": \" — hierna zal je nooit meer een e-mail van ons ontvangen.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"Uitschrijven\", \"type\": \"text\"}]}]}]}, \"version\": 354}', '2025-01-04 12:04:03', '2025-01-04 12:04:03'),
|
|
5
|
+
('3624fe92-3021-4b70-a740-7acac32db6ef', 'Jouw openstaand saldo bij {{organizationName}}', NULL, NULL, NULL, 'UserBalanceIncreaseNotification', '{{greeting}}Je hebt een nieuw openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het ledenportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het ledenportaal.\n\n \n \n \n \n Betalen via het ledenportaal\n \n \n \n \n\nTwijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het ledenportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.Vragen over je openstaand bedrag? Neem dan contact op met {{organizationName}} via {{fromAddress}}OverzichtDit is een momentopname van je huidige openstaande bedrag. Je kan op elk moment naar het ledenportaal gaan om de huidige status te bekijken en te betalen.{{balanceTable}}Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via deze knop — hierna zal je nooit meer een e-mail van ons ontvangen.Uitschrijven', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>Jouw openstaand saldo bij {{organizationName}}</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n}\n\n.email-style-inline-code {\n font-family: monospace;\n white-space: pre-wrap;\n display: inline-block;\n}\n\n.email-style-description-small {\n font-size: 14px;\n line-height: 1.5;\n font-weight: normal;\n color: var(--color-gray-4, #5e5e5e);\n font-variation-settings: \"opsz\" 19;\n}\n\n.email-style-title-list {\n font-size: 16px;\n line-height: 1.3;\n font-weight: 500;\n}\n.email-style-title-list + p {\n padding-top: 3px;\n}\n\n.email-style-title-prefix-list {\n font-size: 11px;\n line-height: 1.5;\n font-weight: bold;\n color: {{primaryColor}};\n text-transform: uppercase;\n margin-bottom: 3px;\n}\n.email-style-title-prefix-list.error {\n color: #f0153d;\n}\n\n.email-style-price-base, .email-style-discount-price, .email-style-discount-old-price, .email-style-price {\n font-size: 15px;\n line-height: 1.4;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n}\n.email-style-price-base.disabled, .disabled.email-style-discount-price, .disabled.email-style-discount-old-price, .disabled.email-style-price {\n opacity: 0.6;\n}\n.email-style-price-base.negative, .negative.email-style-discount-price, .negative.email-style-discount-old-price, .negative.email-style-price {\n color: #f0153d;\n}\n\n.email-style-price {\n font-weight: bold;\n color: {{primaryColor}};\n}\n\n.email-style-discount-old-price {\n text-decoration: line-through;\n color: var(--color-gray-4, #5e5e5e);\n}\n\n.email-style-discount-price {\n font-weight: bold;\n color: #ff4747;\n margin-left: 5px;\n}\n\n.pre-wrap {\n white-space: pre-wrap;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Je hebt een nieuw openstaand bedrag van {{outstandingBalance}} bij {{organizationName}}. Je kan de betaling in orde brengen door naar het ledenportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><strong>Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het ledenportaal.</strong></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"paymentUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{paymentUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Betalen via het ledenportaal</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p class=\"description\" style=\"color: #5e5e5e;\"><em>Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het ledenportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><strong><em>Vragen over je openstaand bedrag</em></strong><em>? Neem dan contact op met </em>{{organizationName}} <em>via </em>{{fromAddress}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><hr style=\"height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;\"><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><h2 style=\"margin: 0; padding: 0;\">Overzicht</h2><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Dit is een momentopname van je huidige openstaande bedrag. Je kan op elk moment naar het ledenportaal gaan om de huidige status te bekijken en te betalen.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartVariableBlock\" data-id=\"balanceTable\">{{balanceTable}}</div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><em>Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via </em><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\"><em>deze knop</em></a><em> — hierna zal je nooit meer een e-mail van ons ontvangen.</em></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><a class=\"inline-link\" href=\"{{unsubscribeUrl}}\" target=\"\" style=\"margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation;\">Uitschrijven</a></p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Je hebt een nieuw openstaand bedrag van \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"outstandingBalance\"}}, {\"text\": \" bij \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \". Je kan de betaling in orde brengen door naar het ledenportaal te gaan. Daar kan je ook een detail bekijken van het openstaande bedrag.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Gelieve niet zomaar geld over te schrijven op onze rekening, maar altijd te betalen via het ledenportaal.\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"paymentUrl\"}, \"content\": [{\"text\": \"Betalen via het ledenportaal\", \"type\": \"text\"}]}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Twijfel je of één van onze e-mails wel echt is? Ga dan zelf rechtstreeks naar het ledenportaal via onze website zonder op een link in een e-mail te klikken. Via die weg kan je ook je openstaand bedrag bekijken en eventueel betalen - dan ben je altijd zeker dat je aan ons betaalt en het geen phishing is.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Vragen over je openstaand bedrag\", \"type\": \"text\", \"marks\": [{\"type\": \"bold\"}, {\"type\": \"italic\"}]}, {\"text\": \"? Neem dan contact op met \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \" \", \"type\": \"text\"}, {\"text\": \"via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"fromAddress\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"horizontalRule\"}, {\"type\": \"paragraph\"}, {\"type\": \"heading\", \"attrs\": {\"level\": 2}, \"content\": [{\"text\": \"Overzicht\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Dit is een momentopname van je huidige openstaande bedrag. Je kan op elk moment naar het ledenportaal gaan om de huidige status te bekijken en te betalen.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartVariableBlock\", \"attrs\": {\"id\": \"balanceTable\"}}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Komt deze e-mail bij jou terecht, maar weet je niet waarover dit gaat en denk je dat dit aan een andere persoon is gericht (bv. een typefout)? Dan schrijf je best uit voor onze e-mails via \", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}, {\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"deze knop\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"text\": \" — hierna zal je nooit meer een e-mail van ons ontvangen.\", \"type\": \"text\", \"marks\": [{\"type\": \"italic\"}]}]}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartButtonInline\", \"attrs\": {\"id\": \"unsubscribeUrl\"}, \"content\": [{\"text\": \"Uitschrijven\", \"type\": \"text\"}]}]}]}, \"version\": 354}', '2025-01-04 10:09:48', '2025-01-04 10:09:48');
|
package/src/models/AuditLog.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { column
|
|
1
|
+
import { column } from '@simonbackx/simple-database';
|
|
2
2
|
import { ArrayDecoder, Decoder, MapDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
|
-
import {
|
|
3
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
4
4
|
import { AuditLogPatchItem, AuditLogReplacement, AuditLogSource, AuditLogType } from '@stamhoofd/structures';
|
|
5
5
|
import { v7 as uuidv7 } from 'uuid';
|
|
6
6
|
|
|
7
|
-
export class AuditLog extends
|
|
7
|
+
export class AuditLog extends QueryableModel {
|
|
8
8
|
static table = 'audit_logs';
|
|
9
9
|
|
|
10
10
|
// Columns
|
|
@@ -67,22 +67,4 @@ export class AuditLog extends Model {
|
|
|
67
67
|
},
|
|
68
68
|
})
|
|
69
69
|
createdAt: Date;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Experimental: needs to move to library
|
|
73
|
-
*/
|
|
74
|
-
static select() {
|
|
75
|
-
const transformer = (row: SQLResultNamespacedRow): AuditLog => {
|
|
76
|
-
const d = (this as typeof AuditLog & typeof Model).fromRow(row[this.table] as any) as AuditLog | undefined;
|
|
77
|
-
|
|
78
|
-
if (!d) {
|
|
79
|
-
throw new Error('EmailTemplate not found');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return d;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const select = new SQLSelect(transformer, SQL.wildcard());
|
|
86
|
-
return select.from(SQL.table(this.table));
|
|
87
|
-
}
|
|
88
70
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { column, Database
|
|
2
|
-
import {
|
|
1
|
+
import { column, Database } from '@simonbackx/simple-database';
|
|
2
|
+
import { BalanceItemPaymentWithPayment, BalanceItemPaymentWithPrivatePayment, BalanceItemRelation, BalanceItemRelationType, BalanceItemStatus, BalanceItem as BalanceItemStruct, BalanceItemType, BalanceItemWithPayments, BalanceItemWithPrivatePayments, Payment as PaymentStruct, PrivatePayment } from '@stamhoofd/structures';
|
|
3
3
|
import { Formatter } from '@stamhoofd/utility';
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
5
5
|
|
|
6
6
|
import { EnumDecoder, MapDecoder } from '@simonbackx/simple-encoding';
|
|
7
|
-
import {
|
|
8
|
-
import { Document,
|
|
7
|
+
import { QueryableModel, SQL } from '@stamhoofd/sql';
|
|
8
|
+
import { Document, MemberUser, Payment } from './';
|
|
9
9
|
import { CachedBalance } from './CachedBalance';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Keeps track of how much a member/user owes or needs to be reimbursed.
|
|
13
13
|
*/
|
|
14
|
-
export class BalanceItem extends
|
|
14
|
+
export class BalanceItem extends QueryableModel {
|
|
15
15
|
static table = 'balance_items';
|
|
16
16
|
|
|
17
17
|
@column({
|
|
@@ -220,8 +220,18 @@ export class BalanceItem extends Model {
|
|
|
220
220
|
await this.deleteItems(items);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
static async getForRegistration(registrationId: string) {
|
|
224
|
-
|
|
223
|
+
static async getForRegistration(registrationId: string, organizationId?: string) {
|
|
224
|
+
let q = BalanceItem.select()
|
|
225
|
+
.where('registrationId', registrationId)
|
|
226
|
+
.whereNot('status', BalanceItemStatus.Hidden);
|
|
227
|
+
|
|
228
|
+
if (organizationId) {
|
|
229
|
+
q = q.where('organizationId', organizationId);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const items = await q
|
|
233
|
+
.fetch();
|
|
234
|
+
|
|
225
235
|
return {
|
|
226
236
|
items,
|
|
227
237
|
...(await this.loadPayments(items)),
|
|
@@ -237,15 +247,6 @@ export class BalanceItem extends Model {
|
|
|
237
247
|
|
|
238
248
|
await BalanceItem.updatePricePaid(items.map(i => i.id));
|
|
239
249
|
|
|
240
|
-
// Deprecated: the member balances have moved to CachedBalance
|
|
241
|
-
// Update outstanding amount of related members and registrations
|
|
242
|
-
const memberIds: string[] = Formatter.uniqueArray(items.map(p => p.memberId).filter(id => id !== null));
|
|
243
|
-
|
|
244
|
-
const Member = (await import('./Member')).Member;
|
|
245
|
-
await Member.updateOutstandingBalance(memberIds);
|
|
246
|
-
|
|
247
|
-
const { Registration } = await import('./Registration');
|
|
248
|
-
|
|
249
250
|
const organizationIds = Formatter.uniqueArray(items.map(p => p.organizationId));
|
|
250
251
|
for (const organizationId of organizationIds) {
|
|
251
252
|
const filteredItems = items.filter(i => i.organizationId === organizationId);
|
|
@@ -253,16 +254,22 @@ export class BalanceItem extends Model {
|
|
|
253
254
|
const memberIds = Formatter.uniqueArray(filteredItems.map(p => p.memberId).filter(id => id !== null));
|
|
254
255
|
await CachedBalance.updateForMembers(organizationId, memberIds);
|
|
255
256
|
|
|
256
|
-
|
|
257
|
+
let userIds = filteredItems.filter(p => p.userId !== null).map(p => p.userId!);
|
|
258
|
+
|
|
259
|
+
if (memberIds.length) {
|
|
260
|
+
// Now also include the userIds of the members
|
|
261
|
+
const userMemberIds = (await MemberUser.select().where('membersId', memberIds).fetch()).map(m => m.usersId);
|
|
262
|
+
userIds.push(...userMemberIds);
|
|
263
|
+
}
|
|
264
|
+
userIds = Formatter.uniqueArray(userIds);
|
|
265
|
+
|
|
257
266
|
await CachedBalance.updateForUsers(organizationId, userIds);
|
|
258
267
|
|
|
259
268
|
const organizationIds = Formatter.uniqueArray(filteredItems.map(p => p.payingOrganizationId).filter(id => id !== null));
|
|
260
269
|
await CachedBalance.updateForOrganizations(organizationId, organizationIds);
|
|
261
270
|
|
|
262
271
|
const registrationIds: string[] = Formatter.uniqueArray(filteredItems.map(p => p.registrationId).filter(id => id !== null));
|
|
263
|
-
|
|
264
|
-
// Deprecated: we'll need to move the outstanding balance of registrations to CachedBalance
|
|
265
|
-
await Registration.updateOutstandingBalance(registrationIds, organizationId);
|
|
272
|
+
await CachedBalance.updateForRegistrations(organizationId, registrationIds);
|
|
266
273
|
|
|
267
274
|
if (registrationIds.length) {
|
|
268
275
|
await Document.updateForRegistrations(registrationIds, organizationId);
|
|
@@ -330,13 +337,6 @@ export class BalanceItem extends Model {
|
|
|
330
337
|
await Database.update(query, params);
|
|
331
338
|
}
|
|
332
339
|
|
|
333
|
-
/**
|
|
334
|
-
* @deprecated
|
|
335
|
-
*/
|
|
336
|
-
static async updatePricePending(balanceItemIds: string[] | 'all') {
|
|
337
|
-
// deprecated
|
|
338
|
-
}
|
|
339
|
-
|
|
340
340
|
static async loadPayments(items: BalanceItem[]) {
|
|
341
341
|
if (items.length == 0) {
|
|
342
342
|
return { balanceItemPayments: [], payments: [] };
|
|
@@ -344,7 +344,9 @@ export class BalanceItem extends Model {
|
|
|
344
344
|
|
|
345
345
|
// Load balance payment items
|
|
346
346
|
const { BalanceItemPayment } = await import('./BalanceItemPayment');
|
|
347
|
-
const balanceItemPayments = await BalanceItemPayment.
|
|
347
|
+
const balanceItemPayments = await BalanceItemPayment.select()
|
|
348
|
+
.where('balanceItemId', items.map(i => i.id))
|
|
349
|
+
.fetch();
|
|
348
350
|
|
|
349
351
|
const payments = await Payment.getByIDs(...balanceItemPayments.map(p => p.paymentId));
|
|
350
352
|
|
|
@@ -461,22 +463,4 @@ export class BalanceItem extends Model {
|
|
|
461
463
|
.whereNot('status', BalanceItemStatus.Hidden)
|
|
462
464
|
.fetch();
|
|
463
465
|
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Experimental: needs to move to library
|
|
467
|
-
*/
|
|
468
|
-
static select() {
|
|
469
|
-
const transformer = (row: SQLResultNamespacedRow): BalanceItem => {
|
|
470
|
-
const d = (this as typeof BalanceItem & typeof Model).fromRow(row[this.table] as any) as BalanceItem | undefined;
|
|
471
|
-
|
|
472
|
-
if (!d) {
|
|
473
|
-
throw new Error('EmailTemplate not found');
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
return d;
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
const select = new SQLSelect(transformer, SQL.wildcard());
|
|
480
|
-
return select.from(SQL.table(this.table));
|
|
481
|
-
}
|
|
482
466
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { column, ManyToOneRelation
|
|
1
|
+
import { column, ManyToOneRelation } from '@simonbackx/simple-database';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
3
|
|
|
4
4
|
import { BalanceItem, Payment } from './';
|
|
5
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Keeps track of all the created payments of a balance item, which contains the (tries) to pay a balance item.
|
|
8
9
|
* It also keeps track of how much a given payment is split between multiple balance items, which makes it possible to pay a balance item partially.
|
|
9
10
|
*/
|
|
10
|
-
export class BalanceItemPayment extends
|
|
11
|
+
export class BalanceItemPayment extends QueryableModel {
|
|
11
12
|
static table = 'balance_item_payments';
|
|
12
13
|
|
|
13
14
|
@column({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { column
|
|
1
|
+
import { column } from '@simonbackx/simple-database';
|
|
2
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
2
3
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
4
|
|
|
4
|
-
export class BuckarooPayment extends
|
|
5
|
+
export class BuckarooPayment extends QueryableModel {
|
|
5
6
|
static table = 'buckaroo_payments';
|
|
6
7
|
|
|
7
8
|
@column({
|