@stamhoofd/models 2.64.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 +2 -2
- package/dist/src/migrations/1605262045-import-postcodes.js +9 -9
- 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 +2 -11
- package/dist/src/models/BalanceItem.d.ts.map +1 -1
- package/dist/src/models/BalanceItem.js +8 -22
- package/dist/src/models/BalanceItem.js.map +1 -1
- package/dist/src/models/BalanceItemPayment.d.ts +3 -7
- package/dist/src/models/BalanceItemPayment.d.ts.map +1 -1
- package/dist/src/models/BalanceItemPayment.js +1 -15
- 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 +7 -9
- package/dist/src/models/CachedBalance.d.ts.map +1 -1
- package/dist/src/models/CachedBalance.js +61 -22
- 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 +2 -1
- 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 +3 -2
- package/dist/src/models/Member.d.ts.map +1 -1
- package/dist/src/models/Member.js +1 -1
- package/dist/src/models/Member.js.map +1 -1
- package/dist/src/models/MemberPlatformMembership.d.ts +2 -7
- package/dist/src/models/MemberPlatformMembership.d.ts.map +1 -1
- package/dist/src/models/MemberPlatformMembership.js +1 -15
- 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 +2 -2
- package/dist/src/models/MergedMember.d.ts.map +1 -1
- package/dist/src/models/MergedMember.js +2 -1
- 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 +3 -3
- package/dist/src/models/Platform.d.ts.map +1 -1
- package/dist/src/models/Platform.js +2 -1
- 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 +3 -2
- package/dist/src/models/Registration.d.ts.map +1 -1
- package/dist/src/models/Registration.js +2 -27
- package/dist/src/models/Registration.js.map +1 -1
- package/dist/src/models/RegistrationPeriod.d.ts +2 -7
- package/dist/src/models/RegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/RegistrationPeriod.js +1 -15
- 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 +4 -5
- 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 +13 -30
- package/src/models/BalanceItemPayment.ts +3 -21
- package/src/models/BuckarooPayment.ts +3 -2
- package/src/models/CachedBalance.ts +82 -27
- package/src/models/Document.ts +4 -3
- package/src/models/DocumentTemplate.ts +4 -3
- 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 +4 -4
- package/src/models/MemberPlatformMembership.ts +3 -21
- package/src/models/MemberResponsibilityRecord.ts +3 -21
- package/src/models/MemberUser.ts +18 -0
- package/src/models/MergedMember.ts +3 -2
- 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 +4 -3
- package/src/models/RegisterCode.ts +3 -2
- package/src/models/Registration.ts +3 -28
- package/src/models/RegistrationPeriod.ts +3 -21
- 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
|
@@ -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
|
|
1
|
+
import { column, Database } from '@simonbackx/simple-database';
|
|
2
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, Payment } from './';
|
|
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({
|
|
@@ -254,7 +254,15 @@ export class BalanceItem extends Model {
|
|
|
254
254
|
const memberIds = Formatter.uniqueArray(filteredItems.map(p => p.memberId).filter(id => id !== null));
|
|
255
255
|
await CachedBalance.updateForMembers(organizationId, memberIds);
|
|
256
256
|
|
|
257
|
-
|
|
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
|
+
|
|
258
266
|
await CachedBalance.updateForUsers(organizationId, userIds);
|
|
259
267
|
|
|
260
268
|
const organizationIds = Formatter.uniqueArray(filteredItems.map(p => p.payingOrganizationId).filter(id => id !== null));
|
|
@@ -329,13 +337,6 @@ export class BalanceItem extends Model {
|
|
|
329
337
|
await Database.update(query, params);
|
|
330
338
|
}
|
|
331
339
|
|
|
332
|
-
/**
|
|
333
|
-
* @deprecated
|
|
334
|
-
*/
|
|
335
|
-
static async updatePricePending(balanceItemIds: string[] | 'all') {
|
|
336
|
-
// deprecated
|
|
337
|
-
}
|
|
338
|
-
|
|
339
340
|
static async loadPayments(items: BalanceItem[]) {
|
|
340
341
|
if (items.length == 0) {
|
|
341
342
|
return { balanceItemPayments: [], payments: [] };
|
|
@@ -462,22 +463,4 @@ export class BalanceItem extends Model {
|
|
|
462
463
|
.whereNot('status', BalanceItemStatus.Hidden)
|
|
463
464
|
.fetch();
|
|
464
465
|
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Experimental: needs to move to library
|
|
468
|
-
*/
|
|
469
|
-
static select() {
|
|
470
|
-
const transformer = (row: SQLResultNamespacedRow): BalanceItem => {
|
|
471
|
-
const d = (this as typeof BalanceItem & typeof Model).fromRow(row[this.table] as any) as BalanceItem | undefined;
|
|
472
|
-
|
|
473
|
-
if (!d) {
|
|
474
|
-
throw new Error('EmailTemplate not found');
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
return d;
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
const select = new SQLSelect(transformer, SQL.wildcard());
|
|
481
|
-
return select.from(SQL.table(this.table));
|
|
482
|
-
}
|
|
483
466
|
}
|
|
@@ -1,14 +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 {
|
|
5
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Keeps track of all the created payments of a balance item, which contains the (tries) to pay a balance item.
|
|
9
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.
|
|
10
10
|
*/
|
|
11
|
-
export class BalanceItemPayment extends
|
|
11
|
+
export class BalanceItemPayment extends QueryableModel {
|
|
12
12
|
static table = 'balance_item_payments';
|
|
13
13
|
|
|
14
14
|
@column({
|
|
@@ -57,22 +57,4 @@ export class BalanceItemPayment extends Model {
|
|
|
57
57
|
|
|
58
58
|
static balanceItem = new ManyToOneRelation(BalanceItem, 'balanceItem');
|
|
59
59
|
static payment = new ManyToOneRelation(Payment, 'payment');
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Experimental: needs to move to library
|
|
63
|
-
*/
|
|
64
|
-
static select() {
|
|
65
|
-
const transformer = (row: SQLResultNamespacedRow): BalanceItemPayment => {
|
|
66
|
-
const d = (this as typeof BalanceItemPayment & typeof Model).fromRow(row[this.table] as any) as BalanceItemPayment | undefined;
|
|
67
|
-
|
|
68
|
-
if (!d) {
|
|
69
|
-
throw new Error('EmailTemplate not found');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return d;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const select = new SQLSelect(transformer, SQL.wildcard());
|
|
76
|
-
return select.from(SQL.table(this.table));
|
|
77
|
-
}
|
|
78
60
|
}
|
|
@@ -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({
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { column
|
|
2
|
-
import { SQL, SQLAlias, SQLMin,
|
|
1
|
+
import { column } from '@simonbackx/simple-database';
|
|
2
|
+
import { QueryableModel, SQL, SQLAlias, SQLMin, SQLSelectAs, SQLSum, SQLWhere, SQLWhereSign } from '@stamhoofd/sql';
|
|
3
3
|
import { BalanceItemStatus, BalanceItem as BalanceItemStruct, ReceivableBalanceType } from '@stamhoofd/structures';
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
5
5
|
import { BalanceItem } from './BalanceItem';
|
|
6
|
+
import { MemberUser } from './MemberUser';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Keeps track of how much a member/user owes or needs to be reimbursed.
|
|
9
10
|
*/
|
|
10
|
-
export class CachedBalance extends
|
|
11
|
+
export class CachedBalance extends QueryableModel {
|
|
11
12
|
static table = 'cached_outstanding_balances';
|
|
12
13
|
|
|
13
14
|
@column({
|
|
@@ -50,6 +51,15 @@ export class CachedBalance extends Model {
|
|
|
50
51
|
@column({ type: 'datetime', nullable: true })
|
|
51
52
|
nextDueAt: Date | null = null;
|
|
52
53
|
|
|
54
|
+
@column({ type: 'datetime', nullable: true })
|
|
55
|
+
lastReminderEmail: Date | null = null;
|
|
56
|
+
|
|
57
|
+
@column({ type: 'integer' })
|
|
58
|
+
lastReminderAmountOpen = 0;
|
|
59
|
+
|
|
60
|
+
@column({ type: 'integer' })
|
|
61
|
+
reminderEmailCount = 0;
|
|
62
|
+
|
|
53
63
|
@column({
|
|
54
64
|
type: 'datetime', beforeSave(old?: any) {
|
|
55
65
|
if (old !== undefined) {
|
|
@@ -108,7 +118,7 @@ export class CachedBalance extends Model {
|
|
|
108
118
|
}
|
|
109
119
|
}
|
|
110
120
|
|
|
111
|
-
static async balanceForObjects(organizationId: string, objectIds: string[], objectType: ReceivableBalanceType) {
|
|
121
|
+
static async balanceForObjects(organizationId: string, objectIds: string[], objectType: ReceivableBalanceType, includeUserMembers = false) {
|
|
112
122
|
if (objectIds.length === 0) {
|
|
113
123
|
return [];
|
|
114
124
|
}
|
|
@@ -119,7 +129,7 @@ export class CachedBalance extends Model {
|
|
|
119
129
|
case ReceivableBalanceType.member:
|
|
120
130
|
return await this.balanceForMembers(organizationId, objectIds);
|
|
121
131
|
case ReceivableBalanceType.user:
|
|
122
|
-
return await this.balanceForUsers(organizationId, objectIds);
|
|
132
|
+
return await this.balanceForUsers(organizationId, objectIds, includeUserMembers);
|
|
123
133
|
case ReceivableBalanceType.registration:
|
|
124
134
|
return await this.balanceForRegistrations(organizationId, objectIds);
|
|
125
135
|
}
|
|
@@ -323,7 +333,7 @@ export class CachedBalance extends Model {
|
|
|
323
333
|
if (result.length === 0) {
|
|
324
334
|
return;
|
|
325
335
|
}
|
|
326
|
-
const query =
|
|
336
|
+
const query = this.insert()
|
|
327
337
|
.columns(
|
|
328
338
|
'id',
|
|
329
339
|
'organizationId',
|
|
@@ -335,6 +345,7 @@ export class CachedBalance extends Model {
|
|
|
335
345
|
'nextDueAt',
|
|
336
346
|
'createdAt',
|
|
337
347
|
'updatedAt',
|
|
348
|
+
'reminderEmailCount',
|
|
338
349
|
)
|
|
339
350
|
.values(...result.map(([objectId, { amountPaid, amountOpen, amountPending, nextDueAt }]) => {
|
|
340
351
|
return [
|
|
@@ -348,6 +359,7 @@ export class CachedBalance extends Model {
|
|
|
348
359
|
nextDueAt,
|
|
349
360
|
new Date(),
|
|
350
361
|
new Date(),
|
|
362
|
+
0,
|
|
351
363
|
];
|
|
352
364
|
}))
|
|
353
365
|
.as('v')
|
|
@@ -357,6 +369,22 @@ export class CachedBalance extends Model {
|
|
|
357
369
|
SQL.assignment('amountPending', SQL.column('v', 'amountPending')),
|
|
358
370
|
SQL.assignment('nextDueAt', SQL.column('v', 'nextDueAt')),
|
|
359
371
|
SQL.assignment('updatedAt', SQL.column('v', 'updatedAt')),
|
|
372
|
+
|
|
373
|
+
// Reset email count if amountOpen is zero
|
|
374
|
+
SQL.assignment(
|
|
375
|
+
'reminderEmailCount',
|
|
376
|
+
SQL.if(SQL.column('v', 'amountOpen'), 0)
|
|
377
|
+
.then(0)
|
|
378
|
+
.else(SQL.column('reminderEmailCount')),
|
|
379
|
+
),
|
|
380
|
+
|
|
381
|
+
// Reset lastReminderEmail if amountOpen is zero
|
|
382
|
+
SQL.assignment(
|
|
383
|
+
'lastReminderEmail',
|
|
384
|
+
SQL.if(SQL.column('v', 'amountOpen'), 0)
|
|
385
|
+
.then(null)
|
|
386
|
+
.else(SQL.column('lastReminderEmail')),
|
|
387
|
+
),
|
|
360
388
|
);
|
|
361
389
|
|
|
362
390
|
await query.insert();
|
|
@@ -390,7 +418,43 @@ export class CachedBalance extends Model {
|
|
|
390
418
|
if (userIds.length === 0) {
|
|
391
419
|
return;
|
|
392
420
|
}
|
|
393
|
-
const results = await this.fetchForObjects(
|
|
421
|
+
const results = await this.fetchForObjects(
|
|
422
|
+
organizationId,
|
|
423
|
+
userIds,
|
|
424
|
+
'userId',
|
|
425
|
+
SQL.where('memberId', null),
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
// We also need to include the balance of the related members for each user
|
|
429
|
+
|
|
430
|
+
// Fetch members of these users
|
|
431
|
+
const memberUsers = await MemberUser.select().where('usersId', userIds).fetch();
|
|
432
|
+
|
|
433
|
+
const memberCachedBalances = await this.getForObjects(memberUsers.map(mu => mu.membersId), organizationId);
|
|
434
|
+
|
|
435
|
+
for (const memberCachedBalance of memberCachedBalances) {
|
|
436
|
+
const userIds = memberUsers.filter(mu => mu.membersId === memberCachedBalance.objectId).map(mu => mu.usersId);
|
|
437
|
+
|
|
438
|
+
for (const userId of userIds) {
|
|
439
|
+
// if already in results: append
|
|
440
|
+
const result = results.find(([objectId]) => objectId === userId);
|
|
441
|
+
|
|
442
|
+
if (result) {
|
|
443
|
+
result[1].amountPaid += memberCachedBalance.amountPaid;
|
|
444
|
+
result[1].amountOpen += memberCachedBalance.amountOpen;
|
|
445
|
+
result[1].amountPending += memberCachedBalance.amountPending;
|
|
446
|
+
if (memberCachedBalance.nextDueAt && (!result[1].nextDueAt || memberCachedBalance.nextDueAt > result[1].nextDueAt)) {
|
|
447
|
+
result[1].nextDueAt = memberCachedBalance.nextDueAt;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
// Not possible
|
|
452
|
+
throw new Error('User not found in results');
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Fetch cached balance of these members and merge the results
|
|
394
458
|
await this.setForResults(organizationId, results, ReceivableBalanceType.user);
|
|
395
459
|
}
|
|
396
460
|
|
|
@@ -408,11 +472,20 @@ export class CachedBalance extends Model {
|
|
|
408
472
|
return await this.fetchBalanceItems(organizationId, memberIds, 'memberId');
|
|
409
473
|
}
|
|
410
474
|
|
|
411
|
-
static async balanceForUsers(organizationId: string, userIds: string[]) {
|
|
475
|
+
static async balanceForUsers(organizationId: string, userIds: string[], includeUserMembers = false) {
|
|
412
476
|
if (userIds.length === 0) {
|
|
413
477
|
return [];
|
|
414
478
|
}
|
|
415
|
-
|
|
479
|
+
const base = await this.fetchBalanceItems(organizationId, userIds, 'userId', SQL.where('memberId', null));
|
|
480
|
+
|
|
481
|
+
if (!includeUserMembers) {
|
|
482
|
+
return base;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const memberUsers = await MemberUser.select().where('usersId', userIds).fetch();
|
|
486
|
+
const memberIds = memberUsers.map(mu => mu.membersId);
|
|
487
|
+
const memberCachedBalances = await this.balanceForMembers(organizationId, memberIds);
|
|
488
|
+
return base.concat(memberCachedBalances);
|
|
416
489
|
}
|
|
417
490
|
|
|
418
491
|
static async balanceForRegistrations(organizationId: string, registrationIds: string[]) {
|
|
@@ -421,22 +494,4 @@ export class CachedBalance extends Model {
|
|
|
421
494
|
}
|
|
422
495
|
return await this.fetchBalanceItems(organizationId, registrationIds, 'registrationId');
|
|
423
496
|
}
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Experimental: needs to move to library
|
|
427
|
-
*/
|
|
428
|
-
static select() {
|
|
429
|
-
const transformer = (row: SQLResultNamespacedRow): CachedBalance => {
|
|
430
|
-
const d = (this as typeof CachedBalance & typeof Model).fromRow(row[this.table] as any) as CachedBalance | undefined;
|
|
431
|
-
|
|
432
|
-
if (!d) {
|
|
433
|
-
throw new Error('EmailTemplate not found');
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
return d;
|
|
437
|
-
};
|
|
438
|
-
|
|
439
|
-
const select = new SQLSelect(transformer, SQL.wildcard());
|
|
440
|
-
return select.from(SQL.table(this.table));
|
|
441
|
-
}
|
|
442
497
|
}
|
package/src/models/Document.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { column
|
|
2
|
-
import { Document as DocumentStruct,
|
|
1
|
+
import { column } from '@simonbackx/simple-database';
|
|
2
|
+
import { DocumentData, DocumentStatus, Document as DocumentStruct, Platform, Version } from '@stamhoofd/structures';
|
|
3
3
|
import { Formatter } from '@stamhoofd/utility';
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
5
5
|
|
|
6
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
6
7
|
import { render } from '../helpers/Handlebars';
|
|
7
8
|
import { RegistrationWithMember } from './Member';
|
|
8
9
|
import { Organization } from './Organization';
|
|
9
10
|
import { Registration } from './Registration';
|
|
10
11
|
|
|
11
|
-
export class Document extends
|
|
12
|
+
export class Document extends QueryableModel {
|
|
12
13
|
static table = 'documents';
|
|
13
14
|
|
|
14
15
|
@column({ primary: true, type: 'string', beforeSave(value) {
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { column
|
|
1
|
+
import { column } from '@simonbackx/simple-database';
|
|
2
2
|
import { isSimpleError, isSimpleErrors, SimpleError } from '@simonbackx/simple-errors';
|
|
3
3
|
import { QueueHandler } from '@stamhoofd/queues';
|
|
4
4
|
import { BalanceItemStatus, DocumentData, DocumentPrivateSettings, DocumentSettings, DocumentStatus, DocumentTemplatePrivate, GroupType, NationalRegisterNumberOptOut, Parent, RecordAddressAnswer, RecordAnswer, RecordAnswerDecoder, RecordDateAnswer, RecordPriceAnswer, RecordSettings, RecordTextAnswer, RecordType } from '@stamhoofd/structures';
|
|
5
5
|
import { Sorter } from '@stamhoofd/utility';
|
|
6
6
|
import { v4 as uuidv4 } from 'uuid';
|
|
7
7
|
|
|
8
|
+
import { QueryableModel } from '@stamhoofd/sql';
|
|
8
9
|
import { render } from '../helpers/Handlebars';
|
|
9
10
|
import { BalanceItem } from './BalanceItem';
|
|
10
11
|
import { Document } from './Document';
|
|
11
12
|
import { Group } from './Group';
|
|
12
13
|
import { Member, RegistrationWithMember } from './Member';
|
|
13
14
|
import { Organization } from './Organization';
|
|
14
|
-
import { User } from './User';
|
|
15
15
|
import { Registration } from './Registration';
|
|
16
|
+
import { User } from './User';
|
|
16
17
|
|
|
17
|
-
export class DocumentTemplate extends
|
|
18
|
+
export class DocumentTemplate extends QueryableModel {
|
|
18
19
|
static table = 'document_templates';
|
|
19
20
|
|
|
20
21
|
@column({ primary: true, type: 'string', beforeSave(value) {
|