@stamhoofd/models 2.39.0 → 2.40.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/factories/AddressFactory.d.ts +3 -4
- package/dist/src/factories/AddressFactory.d.ts.map +1 -1
- package/dist/src/factories/AddressFactory.js +13 -13
- package/dist/src/factories/EmergencyContactFactory.d.ts +3 -4
- package/dist/src/factories/EmergencyContactFactory.d.ts.map +1 -1
- package/dist/src/factories/EmergencyContactFactory.js +27 -27
- package/dist/src/factories/EmergencyContactFactory.js.map +1 -1
- package/dist/src/factories/GroupFactory.d.ts +4 -4
- package/dist/src/factories/GroupFactory.d.ts.map +1 -1
- package/dist/src/factories/GroupFactory.js +8 -8
- package/dist/src/factories/GroupFactory.js.map +1 -1
- package/dist/src/factories/MemberFactory.d.ts +4 -4
- package/dist/src/factories/MemberFactory.d.ts.map +1 -1
- package/dist/src/factories/MemberFactory.js +17 -17
- package/dist/src/factories/MemberFactory.js.map +1 -1
- package/dist/src/factories/OrganizationFactory.d.ts +4 -4
- package/dist/src/factories/OrganizationFactory.js +8 -8
- package/dist/src/factories/OrganizationFactory.js.map +1 -1
- package/dist/src/factories/ParentFactory.d.ts +1 -1
- package/dist/src/factories/ParentFactory.js +19 -19
- package/dist/src/factories/ParentFactory.js.map +1 -1
- package/dist/src/factories/RecordFactory.d.ts +2 -3
- package/dist/src/factories/RecordFactory.d.ts.map +1 -1
- package/dist/src/factories/RecordFactory.js +1 -1
- package/dist/src/factories/RecordFactory.js.map +1 -1
- package/dist/src/factories/RegisterCodeFactory.d.ts +2 -2
- package/dist/src/factories/RegisterCodeFactory.d.ts.map +1 -1
- package/dist/src/factories/RegisterCodeFactory.js +2 -2
- package/dist/src/factories/RegistrationFactory.d.ts +3 -3
- package/dist/src/factories/RegistrationFactory.d.ts.map +1 -1
- package/dist/src/factories/RegistrationFactory.js.map +1 -1
- package/dist/src/factories/RegistrationPeriodFactory.d.ts +2 -2
- package/dist/src/factories/RegistrationPeriodFactory.js.map +1 -1
- package/dist/src/factories/UserFactory.d.ts +3 -3
- package/dist/src/factories/UserFactory.d.ts.map +1 -1
- package/dist/src/factories/UserFactory.js +3 -3
- package/dist/src/factories/UserFactory.js.map +1 -1
- package/dist/src/factories/WebshopFactory.d.ts +4 -4
- package/dist/src/factories/WebshopFactory.d.ts.map +1 -1
- package/dist/src/factories/WebshopFactory.js +1 -1
- package/dist/src/factories/WebshopFactory.js.map +1 -1
- package/dist/src/helpers/DNSValidator.d.ts +1 -1
- package/dist/src/helpers/DNSValidator.d.ts.map +1 -1
- package/dist/src/helpers/DNSValidator.js +33 -33
- package/dist/src/helpers/DNSValidator.js.map +1 -1
- package/dist/src/helpers/EmailBuilder.d.ts +10 -10
- package/dist/src/helpers/EmailBuilder.d.ts.map +1 -1
- package/dist/src/helpers/EmailBuilder.js +34 -34
- package/dist/src/helpers/EmailBuilder.js.map +1 -1
- package/dist/src/helpers/GroupBuilder.d.ts.map +1 -1
- package/dist/src/helpers/GroupBuilder.js +57 -57
- package/dist/src/helpers/GroupBuilder.js.map +1 -1
- package/dist/src/helpers/Handlebars.d.ts.map +1 -1
- package/dist/src/helpers/Handlebars.js +29 -29
- package/dist/src/helpers/Handlebars.js.map +1 -1
- package/dist/src/helpers/MemberMerger.d.ts +1 -1
- package/dist/src/helpers/MemberMerger.d.ts.map +1 -1
- package/dist/src/helpers/MemberMerger.js +33 -33
- package/dist/src/helpers/MemberMerger.js.map +1 -1
- package/dist/src/helpers/MemberMerger.test.js +194 -194
- package/dist/src/helpers/MemberMerger.test.js.map +1 -1
- package/dist/src/helpers/RateLimiter.d.ts.map +1 -1
- package/dist/src/helpers/RateLimiter.js +2 -2
- package/dist/src/helpers/RateLimiter.js.map +1 -1
- package/dist/src/helpers/SetupStepsUpdater.d.ts +22 -0
- package/dist/src/helpers/SetupStepsUpdater.d.ts.map +1 -0
- package/dist/src/helpers/SetupStepsUpdater.js +255 -0
- package/dist/src/helpers/SetupStepsUpdater.js.map +1 -0
- package/dist/src/helpers/WebshopCounter.d.ts +1 -1
- package/dist/src/helpers/WebshopCounter.d.ts.map +1 -1
- package/dist/src/helpers/WebshopCounter.js +1 -1
- package/dist/src/helpers/WebshopCounter.js.map +1 -1
- package/dist/src/helpers/WebshopCounter.test.js +6 -6
- package/dist/src/helpers/WebshopCounter.test.js.map +1 -1
- package/dist/src/index.d.ts +20 -19
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrations/1605262045-import-postcodes.js +12 -12
- package/dist/src/migrations/1605262046-import-postcodes-nl.js +10 -10
- package/dist/src/models/BalanceItem.d.ts.map +1 -1
- package/dist/src/models/BalanceItem.js +37 -37
- package/dist/src/models/BalanceItem.js.map +1 -1
- package/dist/src/models/BalanceItemPayment.d.ts.map +1 -1
- package/dist/src/models/BalanceItemPayment.js +13 -13
- package/dist/src/models/BalanceItemPayment.js.map +1 -1
- package/dist/src/models/BuckarooPayment.d.ts +1 -1
- package/dist/src/models/BuckarooPayment.d.ts.map +1 -1
- package/dist/src/models/BuckarooPayment.js +5 -5
- package/dist/src/models/BuckarooPayment.js.map +1 -1
- package/dist/src/models/CachedOutstandingBalance.d.ts.map +1 -1
- package/dist/src/models/CachedOutstandingBalance.js +37 -37
- package/dist/src/models/CachedOutstandingBalance.js.map +1 -1
- package/dist/src/models/Document.d.ts +4 -4
- package/dist/src/models/Document.d.ts.map +1 -1
- package/dist/src/models/Document.js +27 -27
- package/dist/src/models/Document.js.map +1 -1
- package/dist/src/models/DocumentTemplate.d.ts +4 -4
- package/dist/src/models/DocumentTemplate.d.ts.map +1 -1
- package/dist/src/models/DocumentTemplate.js +72 -72
- package/dist/src/models/DocumentTemplate.js.map +1 -1
- package/dist/src/models/Email.d.ts.map +1 -1
- package/dist/src/models/Email.js +63 -64
- package/dist/src/models/Email.js.map +1 -1
- package/dist/src/models/EmailRecipient.d.ts.map +1 -1
- package/dist/src/models/EmailRecipient.js +20 -20
- package/dist/src/models/EmailRecipient.js.map +1 -1
- package/dist/src/models/EmailTemplate.d.ts +3 -3
- package/dist/src/models/EmailTemplate.d.ts.map +1 -1
- package/dist/src/models/EmailTemplate.js +16 -16
- 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 +57 -55
- 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 +15 -15
- package/dist/src/models/Event.js.map +1 -1
- package/dist/src/models/Group.d.ts +3 -1
- package/dist/src/models/Group.d.ts.map +1 -1
- package/dist/src/models/Group.js +46 -35
- package/dist/src/models/Group.js.map +1 -1
- package/dist/src/models/Image.d.ts +1 -1
- package/dist/src/models/Image.d.ts.map +1 -1
- package/dist/src/models/Image.js +26 -26
- package/dist/src/models/Image.js.map +1 -1
- package/dist/src/models/Member.d.ts +8 -8
- package/dist/src/models/Member.d.ts.map +1 -1
- package/dist/src/models/Member.js +60 -60
- package/dist/src/models/Member.js.map +1 -1
- package/dist/src/models/MemberPlatformMembership.d.ts +3 -3
- package/dist/src/models/MemberPlatformMembership.d.ts.map +1 -1
- package/dist/src/models/MemberPlatformMembership.js +26 -26
- package/dist/src/models/MemberPlatformMembership.js.map +1 -1
- package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -1
- package/dist/src/models/MemberResponsibilityRecord.js +13 -13
- package/dist/src/models/MemberResponsibilityRecord.js.map +1 -1
- 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 +19 -19
- package/dist/src/models/MergedMember.js.map +1 -1
- package/dist/src/models/MolliePayment.d.ts +1 -1
- package/dist/src/models/MolliePayment.d.ts.map +1 -1
- package/dist/src/models/MolliePayment.js +5 -5
- package/dist/src/models/MolliePayment.js.map +1 -1
- package/dist/src/models/MollieToken.d.ts.map +1 -1
- package/dist/src/models/MollieToken.js +60 -60
- 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 +13 -13
- package/dist/src/models/OneTimeToken.js.map +1 -1
- package/dist/src/models/Order.d.ts +1 -1
- package/dist/src/models/Order.d.ts.map +1 -1
- package/dist/src/models/Order.js +70 -70
- package/dist/src/models/Order.js.map +1 -1
- package/dist/src/models/Organization.d.ts +5 -5
- package/dist/src/models/Organization.d.ts.map +1 -1
- package/dist/src/models/Organization.js +127 -127
- package/dist/src/models/Organization.js.map +1 -1
- package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/OrganizationRegistrationPeriod.js +15 -15
- package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -1
- package/dist/src/models/PasswordToken.d.ts +3 -3
- package/dist/src/models/PasswordToken.d.ts.map +1 -1
- package/dist/src/models/PasswordToken.js +17 -17
- package/dist/src/models/PasswordToken.js.map +1 -1
- package/dist/src/models/PayconiqPayment.d.ts +1 -1
- package/dist/src/models/PayconiqPayment.d.ts.map +1 -1
- package/dist/src/models/PayconiqPayment.js +49 -49
- package/dist/src/models/PayconiqPayment.js.map +1 -1
- package/dist/src/models/Payment.d.ts +3 -3
- package/dist/src/models/Payment.d.ts.map +1 -1
- package/dist/src/models/Payment.js +36 -36
- package/dist/src/models/Payment.js.map +1 -1
- package/dist/src/models/Platform.d.ts +2 -2
- package/dist/src/models/Platform.d.ts.map +1 -1
- package/dist/src/models/Platform.js +8 -8
- package/dist/src/models/Platform.js.map +1 -1
- package/dist/src/models/RegisterCode.d.ts +1 -1
- package/dist/src/models/RegisterCode.d.ts.map +1 -1
- package/dist/src/models/RegisterCode.js +11 -11
- package/dist/src/models/RegisterCode.js.map +1 -1
- package/dist/src/models/Registration.d.ts +1 -1
- package/dist/src/models/Registration.d.ts.map +1 -1
- package/dist/src/models/Registration.js +88 -88
- package/dist/src/models/Registration.js.map +1 -1
- package/dist/src/models/RegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/RegistrationPeriod.js +12 -12
- package/dist/src/models/RegistrationPeriod.js.map +1 -1
- package/dist/src/models/STCredit.d.ts +1 -1
- package/dist/src/models/STCredit.d.ts.map +1 -1
- package/dist/src/models/STCredit.js +12 -12
- package/dist/src/models/STCredit.js.map +1 -1
- package/dist/src/models/STInvoice.d.ts +1 -1
- package/dist/src/models/STInvoice.d.ts.map +1 -1
- package/dist/src/models/STInvoice.js +16 -16
- package/dist/src/models/STInvoice.js.map +1 -1
- package/dist/src/models/STPackage.d.ts +1 -1
- package/dist/src/models/STPackage.d.ts.map +1 -1
- package/dist/src/models/STPackage.js +39 -39
- package/dist/src/models/STPackage.js.map +1 -1
- package/dist/src/models/STPendingInvoice.d.ts +1 -1
- package/dist/src/models/STPendingInvoice.d.ts.map +1 -1
- package/dist/src/models/STPendingInvoice.js +11 -11
- package/dist/src/models/STPendingInvoice.js.map +1 -1
- package/dist/src/models/StripeAccount.d.ts.map +1 -1
- package/dist/src/models/StripeAccount.js +13 -13
- package/dist/src/models/StripeAccount.js.map +1 -1
- package/dist/src/models/StripeCheckoutSession.d.ts +1 -1
- package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -1
- package/dist/src/models/StripeCheckoutSession.js +7 -7
- package/dist/src/models/StripeCheckoutSession.js.map +1 -1
- package/dist/src/models/StripePaymentIntent.d.ts +1 -1
- package/dist/src/models/StripePaymentIntent.d.ts.map +1 -1
- package/dist/src/models/StripePaymentIntent.js +7 -7
- package/dist/src/models/StripePaymentIntent.js.map +1 -1
- package/dist/src/models/Ticket.d.ts +2 -2
- package/dist/src/models/Ticket.d.ts.map +1 -1
- package/dist/src/models/Ticket.js +23 -23
- package/dist/src/models/Ticket.js.map +1 -1
- package/dist/src/models/Token.d.ts +3 -3
- package/dist/src/models/Token.d.ts.map +1 -1
- package/dist/src/models/Token.js +27 -27
- package/dist/src/models/Token.js.map +1 -1
- package/dist/src/models/Token.test.js +11 -11
- package/dist/src/models/UsedRegisterCode.d.ts +1 -1
- package/dist/src/models/UsedRegisterCode.d.ts.map +1 -1
- package/dist/src/models/UsedRegisterCode.js +10 -10
- package/dist/src/models/UsedRegisterCode.js.map +1 -1
- package/dist/src/models/User.d.ts +4 -4
- package/dist/src/models/User.d.ts.map +1 -1
- package/dist/src/models/User.js +53 -51
- package/dist/src/models/User.js.map +1 -1
- package/dist/src/models/UserPermissions.d.ts +3 -3
- package/dist/src/models/UserPermissions.d.ts.map +1 -1
- package/dist/src/models/UserPermissions.js +12 -12
- package/dist/src/models/UserPermissions.js.map +1 -1
- package/dist/src/models/Webshop.d.ts +1 -1
- package/dist/src/models/Webshop.d.ts.map +1 -1
- package/dist/src/models/Webshop.js +23 -23
- package/dist/src/models/Webshop.js.map +1 -1
- package/dist/src/models/WebshopDiscountCode.d.ts +1 -1
- package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -1
- package/dist/src/models/WebshopDiscountCode.js +16 -16
- package/dist/src/models/WebshopDiscountCode.js.map +1 -1
- package/dist/src/models/addresses/City.d.ts.map +1 -1
- package/dist/src/models/addresses/City.js +9 -9
- package/dist/src/models/addresses/City.js.map +1 -1
- package/dist/src/models/addresses/PostalCode.d.ts.map +1 -1
- package/dist/src/models/addresses/PostalCode.js +11 -11
- package/dist/src/models/addresses/PostalCode.js.map +1 -1
- package/dist/src/models/addresses/PostalCode.test.js +22 -22
- package/dist/src/models/addresses/PostalCode.test.js.map +1 -1
- package/dist/src/models/addresses/Province.d.ts.map +1 -1
- package/dist/src/models/addresses/Province.js +5 -5
- package/dist/src/models/addresses/Province.js.map +1 -1
- package/dist/src/models/addresses/Street.d.ts.map +1 -1
- package/dist/src/models/addresses/Street.js +6 -6
- package/dist/src/models/addresses/Street.js.map +1 -1
- package/dist/src/models/index.d.ts +46 -46
- package/dist/src/models/index.d.ts.map +1 -1
- package/dist/src/models/index.js +0 -1
- package/dist/src/models/index.js.map +1 -1
- package/dist/src/structures/OrganizationServerMetaData.d.ts.map +1 -1
- package/dist/src/structures/OrganizationServerMetaData.js +4 -4
- package/dist/src/structures/OrganizationServerMetaData.js.map +1 -1
- package/dist/tests/jest.global.setup.d.ts.map +1 -1
- package/dist/tests/jest.global.setup.js +15 -13
- package/dist/tests/jest.global.setup.js.map +1 -1
- package/dist/tests/jest.setup.js +3 -1
- package/dist/tests/jest.setup.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +3 -3
- package/src/factories/AddressFactory.ts +17 -17
- package/src/factories/EmergencyContactFactory.ts +30 -31
- package/src/factories/GroupFactory.ts +30 -30
- package/src/factories/MemberFactory.ts +41 -38
- package/src/factories/OrganizationFactory.ts +15 -15
- package/src/factories/ParentFactory.ts +24 -24
- package/src/factories/RecordFactory.ts +5 -4
- package/src/factories/RegisterCodeFactory.ts +7 -7
- package/src/factories/RegistrationFactory.ts +16 -16
- package/src/factories/RegistrationPeriodFactory.ts +5 -5
- package/src/factories/UserFactory.ts +20 -19
- package/src/factories/WebshopFactory.ts +14 -14
- package/src/helpers/DNSValidator.ts +89 -84
- package/src/helpers/EmailBuilder.ts +141 -135
- package/src/helpers/GroupBuilder.ts +181 -181
- package/src/helpers/Handlebars.ts +57 -54
- package/src/helpers/MemberMerger.test.ts +702 -702
- package/src/helpers/MemberMerger.ts +83 -77
- package/src/helpers/RateLimiter.ts +25 -27
- package/src/helpers/SetupStepsUpdater.ts +402 -0
- package/src/helpers/WebshopCounter.test.ts +12 -12
- package/src/helpers/WebshopCounter.ts +20 -19
- package/src/index.ts +20 -19
- package/src/migrations/1605262045-import-postcodes.ts +59 -63
- package/src/migrations/1605262046-import-postcodes-nl.ts +41 -43
- package/src/models/BalanceItem.ts +173 -172
- package/src/models/BalanceItemPayment.ts +32 -33
- package/src/models/BuckarooPayment.ts +7 -7
- package/src/models/CachedOutstandingBalance.ts +98 -99
- package/src/models/Document.ts +90 -87
- package/src/models/DocumentTemplate.ts +207 -198
- package/src/models/Email.ts +198 -200
- package/src/models/EmailRecipient.ts +38 -39
- package/src/models/EmailTemplate.ts +36 -37
- package/src/models/EmailVerificationCode.ts +146 -142
- package/src/models/Event.ts +53 -53
- package/src/models/Group.ts +136 -123
- package/src/models/Image.ts +48 -48
- package/src/models/Member.ts +277 -275
- package/src/models/MemberPlatformMembership.ts +71 -71
- package/src/models/MemberResponsibilityRecord.ts +32 -32
- package/src/models/MergedMember.ts +77 -77
- package/src/models/MolliePayment.ts +7 -7
- package/src/models/MollieToken.ts +131 -126
- package/src/models/OneTimeToken.ts +40 -39
- package/src/models/Order.ts +379 -372
- package/src/models/Organization.ts +332 -325
- package/src/models/OrganizationRegistrationPeriod.ts +50 -50
- package/src/models/PasswordToken.ts +42 -42
- package/src/models/PayconiqPayment.ts +80 -76
- package/src/models/Payment.ts +86 -86
- package/src/models/Platform.ts +21 -22
- package/src/models/RegisterCode.ts +26 -26
- package/src/models/Registration.ts +167 -168
- package/src/models/RegistrationPeriod.ts +29 -29
- package/src/models/STCredit.ts +24 -25
- package/src/models/STInvoice.ts +34 -34
- package/src/models/STPackage.ts +143 -136
- package/src/models/STPendingInvoice.ts +26 -26
- package/src/models/StripeAccount.ts +27 -27
- package/src/models/StripeCheckoutSession.ts +10 -10
- package/src/models/StripePaymentIntent.ts +10 -10
- package/src/models/Ticket.ts +51 -52
- package/src/models/Token.test.ts +13 -13
- package/src/models/Token.ts +64 -63
- package/src/models/UsedRegisterCode.ts +20 -21
- package/src/models/User.ts +148 -144
- package/src/models/UserPermissions.ts +25 -28
- package/src/models/Webshop.ts +53 -53
- package/src/models/WebshopDiscountCode.ts +33 -33
- package/src/models/addresses/City.ts +12 -12
- package/src/models/addresses/PostalCode.test.ts +68 -69
- package/src/models/addresses/PostalCode.ts +57 -57
- package/src/models/addresses/Province.ts +8 -8
- package/src/models/addresses/Street.ts +10 -12
- package/src/models/index.ts +54 -55
- package/src/structures/OrganizationServerMetaData.ts +36 -36
package/src/models/Order.ts
CHANGED
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
import { column, ManyToOneRelation, Model } from
|
|
2
|
-
import { SimpleError } from
|
|
1
|
+
import { column, ManyToOneRelation, Model } from '@simonbackx/simple-database';
|
|
2
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
3
3
|
import { Email } from '@stamhoofd/email';
|
|
4
|
-
import { QueueHandler } from
|
|
4
|
+
import { QueueHandler } from '@stamhoofd/queues';
|
|
5
5
|
import { BalanceItemPaymentWithPayment, BalanceItemPaymentWithPrivatePayment, BalanceItemWithPayments, BalanceItemWithPrivatePayments, EmailTemplateType, OrderData, OrderStatus, Order as OrderStruct, PaymentMethod, Payment as PaymentStruct, PrivateOrder, PrivatePayment, ProductType, Recipient, Replacement, WebshopPreview, WebshopStatus, WebshopTicketType, WebshopTimeSlot } from '@stamhoofd/structures';
|
|
6
|
-
import { Formatter } from
|
|
7
|
-
import { v4 as uuidv4 } from
|
|
6
|
+
import { Formatter } from '@stamhoofd/utility';
|
|
7
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
8
8
|
|
|
9
|
-
import { getEmailBuilderForTemplate, sendEmailTemplate } from
|
|
9
|
+
import { getEmailBuilderForTemplate, sendEmailTemplate } from '../helpers/EmailBuilder';
|
|
10
10
|
import { WebshopCounter } from '../helpers/WebshopCounter';
|
|
11
11
|
import { BalanceItem, Organization, Payment, Ticket, Webshop, WebshopDiscountCode } from './';
|
|
12
12
|
|
|
13
13
|
export class Order extends Model {
|
|
14
|
-
static table =
|
|
14
|
+
static table = 'webshop_orders';
|
|
15
15
|
|
|
16
16
|
// Columns
|
|
17
17
|
@column({
|
|
18
|
-
primary: true, type:
|
|
18
|
+
primary: true, type: 'string', beforeSave(value) {
|
|
19
19
|
return value ?? uuidv4();
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
21
|
})
|
|
22
22
|
id!: string;
|
|
23
23
|
|
|
24
|
-
@column({ foreignKey: Order.organization, type:
|
|
24
|
+
@column({ foreignKey: Order.organization, type: 'string' })
|
|
25
25
|
organizationId: string;
|
|
26
26
|
|
|
27
|
-
@column({ foreignKey: Order.webshop, type:
|
|
27
|
+
@column({ foreignKey: Order.webshop, type: 'string' })
|
|
28
28
|
webshopId: string;
|
|
29
29
|
|
|
30
|
-
@column({ type:
|
|
31
|
-
paymentId: string | null = null
|
|
30
|
+
@column({ type: 'string', nullable: true, foreignKey: Order.payment })
|
|
31
|
+
paymentId: string | null = null;
|
|
32
|
+
|
|
33
|
+
@column({ type: 'string', nullable: true })
|
|
34
|
+
userId: string | null = null;
|
|
32
35
|
|
|
33
|
-
@column({ type:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@column({ type: "json", decoder: OrderData })
|
|
37
|
-
data: OrderData
|
|
36
|
+
@column({ type: 'json', decoder: OrderData })
|
|
37
|
+
data: OrderData;
|
|
38
38
|
|
|
39
|
-
@column({ type:
|
|
40
|
-
number: number | null = null
|
|
39
|
+
@column({ type: 'integer', nullable: true })
|
|
40
|
+
number: number | null = null;
|
|
41
41
|
|
|
42
42
|
@column({
|
|
43
|
-
type:
|
|
43
|
+
type: 'datetime', beforeSave(old?: any) {
|
|
44
44
|
if (old !== undefined) {
|
|
45
45
|
return old;
|
|
46
46
|
}
|
|
47
|
-
const date = new Date()
|
|
48
|
-
date.setMilliseconds(0)
|
|
49
|
-
return date
|
|
50
|
-
}
|
|
47
|
+
const date = new Date();
|
|
48
|
+
date.setMilliseconds(0);
|
|
49
|
+
return date;
|
|
50
|
+
},
|
|
51
51
|
})
|
|
52
|
-
createdAt: Date
|
|
52
|
+
createdAt: Date;
|
|
53
53
|
|
|
54
54
|
@column({
|
|
55
|
-
type:
|
|
56
|
-
const date = new Date()
|
|
57
|
-
date.setMilliseconds(0)
|
|
58
|
-
return date
|
|
55
|
+
type: 'datetime', beforeSave() {
|
|
56
|
+
const date = new Date();
|
|
57
|
+
date.setMilliseconds(0);
|
|
58
|
+
return date;
|
|
59
59
|
},
|
|
60
|
-
skipUpdate: true
|
|
60
|
+
skipUpdate: true,
|
|
61
61
|
})
|
|
62
|
-
updatedAt: Date
|
|
62
|
+
updatedAt: Date;
|
|
63
63
|
|
|
64
|
-
@column({ type:
|
|
65
|
-
validAt: Date | null = null
|
|
64
|
+
@column({ type: 'datetime', nullable: true })
|
|
65
|
+
validAt: Date | null = null;
|
|
66
66
|
|
|
67
|
-
@column({ type:
|
|
68
|
-
status = OrderStatus.Created
|
|
67
|
+
@column({ type: 'string' })
|
|
68
|
+
status = OrderStatus.Created;
|
|
69
69
|
|
|
70
|
-
static webshop = new ManyToOneRelation(Webshop,
|
|
71
|
-
static payment = new ManyToOneRelation(Payment,
|
|
72
|
-
static organization = new ManyToOneRelation(Organization,
|
|
70
|
+
static webshop = new ManyToOneRelation(Webshop, 'webshop');
|
|
71
|
+
static payment = new ManyToOneRelation(Payment, 'payment');
|
|
72
|
+
static organization = new ManyToOneRelation(Organization, 'organization');
|
|
73
73
|
|
|
74
74
|
getTransferReplacements(): { [key: string]: string } {
|
|
75
75
|
return {
|
|
76
|
-
nr: this.number?.toString() ??
|
|
76
|
+
nr: this.number?.toString() ?? '',
|
|
77
77
|
email: this.data.customer.email ?? '',
|
|
78
78
|
phone: this.data.customer.phone ?? '',
|
|
79
79
|
name: this.data.customer.name ?? '',
|
|
80
80
|
naam: this.data.customer.name ?? '',
|
|
81
|
-
}
|
|
81
|
+
};
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
getUrl(this: Order & { webshop: Webshop & { organization: Organization } }) {
|
|
85
85
|
// Country locales are disabled on webshops (always the same country). But we need to add the language if it isn't the same as the organization default language
|
|
86
|
-
let locale =
|
|
87
|
-
if (this.data.consumerLanguage
|
|
88
|
-
locale =
|
|
86
|
+
let locale = '';
|
|
87
|
+
if (this.data.consumerLanguage !== this.webshop.organization.i18n.language) {
|
|
88
|
+
locale = '/' + this.data.consumerLanguage;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
return
|
|
91
|
+
return 'https://' + this.webshop.getHost() + locale + '/order/' + this.id;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
generateBalanceDescription(webshop: Webshop) {
|
|
95
95
|
if (!this.number) {
|
|
96
|
-
return 'Bestelling - ' + webshop.meta.name
|
|
96
|
+
return 'Bestelling - ' + webshop.meta.name;
|
|
97
97
|
}
|
|
98
|
-
return 'Bestelling #' + this.number.toString() + ' - ' + webshop.meta.name
|
|
98
|
+
return 'Bestelling #' + this.number.toString() + ' - ' + webshop.meta.name;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
* Fetch an order
|
|
103
103
|
*/
|
|
104
104
|
static async getForPayment(organizationId: string | null, paymentId: string): Promise<Order | undefined> {
|
|
105
|
-
const order = (await this.where({ paymentId }, { limit: 1 }))[0]
|
|
105
|
+
const order = (await this.where({ paymentId }, { limit: 1 }))[0];
|
|
106
106
|
if (!order) {
|
|
107
|
-
return
|
|
107
|
+
return;
|
|
108
108
|
}
|
|
109
109
|
if (organizationId !== null && order.organizationId !== organizationId) {
|
|
110
110
|
// Security check
|
|
111
|
-
return
|
|
111
|
+
return;
|
|
112
112
|
}
|
|
113
|
-
return order
|
|
113
|
+
return order;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
shouldIncludeStock() {
|
|
117
|
-
return this.status !== OrderStatus.Canceled && this.status !== OrderStatus.Deleted
|
|
117
|
+
return this.status !== OrderStatus.Canceled && this.status !== OrderStatus.Deleted;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
async shouldCreateTickets() {
|
|
@@ -127,7 +127,7 @@ export class Order extends Model {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
// Check we paid at least 1 cent
|
|
130
|
-
const allBalanceItems = await BalanceItem.where({ orderId: this.id })
|
|
130
|
+
const allBalanceItems = await BalanceItem.where({ orderId: this.id });
|
|
131
131
|
if (allBalanceItems.find(b => b.pricePaid > 0)) {
|
|
132
132
|
return true;
|
|
133
133
|
}
|
|
@@ -137,91 +137,91 @@ export class Order extends Model {
|
|
|
137
137
|
|
|
138
138
|
get totalToPay() {
|
|
139
139
|
if (this.status === OrderStatus.Canceled || this.status === OrderStatus.Deleted) {
|
|
140
|
-
return 0
|
|
140
|
+
return 0;
|
|
141
141
|
}
|
|
142
|
-
return this.data.totalPrice
|
|
142
|
+
return this.data.totalPrice;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
async undoPaymentFailed(this: Order, _payment: Payment | null, _organization: Organization) {
|
|
146
146
|
if (this.status !== OrderStatus.Deleted && this.status !== OrderStatus.Canceled) {
|
|
147
|
-
this.markUpdated()
|
|
148
|
-
await this.save()
|
|
149
|
-
|
|
147
|
+
this.markUpdated();
|
|
148
|
+
await this.save();
|
|
149
|
+
|
|
150
150
|
const webshop = await Webshop.getByID(this.webshopId);
|
|
151
151
|
if (webshop) {
|
|
152
|
-
await this.setRelation(Order.webshop, webshop).updateTickets()
|
|
152
|
+
await this.setRelation(Order.webshop, webshop).updateTickets();
|
|
153
153
|
}
|
|
154
|
-
return
|
|
154
|
+
return;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
console.log('Undoing payment failed for order '+this.id)
|
|
158
|
-
this.markUpdated()
|
|
159
|
-
this.status = OrderStatus.Created
|
|
160
|
-
await this.save()
|
|
157
|
+
console.log('Undoing payment failed for order ' + this.id);
|
|
158
|
+
this.markUpdated();
|
|
159
|
+
this.status = OrderStatus.Created;
|
|
160
|
+
await this.save();
|
|
161
161
|
|
|
162
|
-
const webshop = await QueueHandler.schedule(
|
|
162
|
+
const webshop = await QueueHandler.schedule('webshop-stock/' + this.webshopId, async () => {
|
|
163
163
|
// Fetch webshop inside queue to make sure the stock is up to date
|
|
164
164
|
const webshop = await Webshop.getByID(this.webshopId);
|
|
165
165
|
if (!webshop) {
|
|
166
166
|
// ignore for now
|
|
167
|
-
console.error(
|
|
168
|
-
return
|
|
167
|
+
console.error('Missing webshop with id ' + this.webshopId + ' in webshop stock queue for order ' + this.id);
|
|
168
|
+
return;
|
|
169
169
|
}
|
|
170
|
-
|
|
171
|
-
await this.setRelation(Order.webshop, webshop).updateStock() // readd reserved stock
|
|
170
|
+
|
|
171
|
+
await this.setRelation(Order.webshop, webshop).updateStock(); // readd reserved stock
|
|
172
172
|
return webshop;
|
|
173
|
-
})
|
|
173
|
+
});
|
|
174
174
|
|
|
175
175
|
if (webshop) {
|
|
176
|
-
await this.setRelation(Order.webshop, webshop).updateTickets()
|
|
176
|
+
await this.setRelation(Order.webshop, webshop).updateTickets();
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
async deleteOrderBecauseOfCreationError(this: Order) {
|
|
181
|
-
this.status = OrderStatus.Deleted
|
|
182
|
-
await this.save()
|
|
181
|
+
this.status = OrderStatus.Deleted;
|
|
182
|
+
await this.save();
|
|
183
183
|
|
|
184
|
-
const webshop = await QueueHandler.schedule(
|
|
184
|
+
const webshop = await QueueHandler.schedule('webshop-stock/' + this.webshopId, async () => {
|
|
185
185
|
// Fetch webshop inside queue to make sure the stock is up to date
|
|
186
186
|
const webshop = await Webshop.getByID(this.webshopId);
|
|
187
187
|
if (!webshop) {
|
|
188
188
|
// ignore for now
|
|
189
|
-
console.error(
|
|
190
|
-
return
|
|
189
|
+
console.error('Missing webshop with id ' + this.webshopId + ' in webshop stock queue for order ' + this.id);
|
|
190
|
+
return;
|
|
191
191
|
}
|
|
192
|
-
|
|
193
|
-
await this.setRelation(Order.webshop, webshop).updateStock() // readd reserved stock
|
|
192
|
+
|
|
193
|
+
await this.setRelation(Order.webshop, webshop).updateStock(); // readd reserved stock
|
|
194
194
|
return webshop;
|
|
195
|
-
})
|
|
195
|
+
});
|
|
196
196
|
|
|
197
197
|
if (webshop) {
|
|
198
|
-
await this.setRelation(Order.webshop, webshop).updateTickets()
|
|
198
|
+
await this.setRelation(Order.webshop, webshop).updateTickets();
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
async onPaymentFailed(this: Order, payment: Payment | null, organization: Organization) {
|
|
203
203
|
if (this.shouldIncludeStock()) {
|
|
204
|
-
this.markUpdated()
|
|
204
|
+
this.markUpdated();
|
|
205
205
|
if (this.number === null) {
|
|
206
|
-
this.status = OrderStatus.Deleted
|
|
206
|
+
this.status = OrderStatus.Deleted;
|
|
207
207
|
}
|
|
208
|
-
await this.save()
|
|
208
|
+
await this.save();
|
|
209
209
|
|
|
210
|
-
const webshop = await QueueHandler.schedule(
|
|
210
|
+
const webshop = await QueueHandler.schedule('webshop-stock/' + this.webshopId, async () => {
|
|
211
211
|
// Fetch webshop inside queue to make sure the stock is up to date
|
|
212
212
|
const webshop = await Webshop.getByID(this.webshopId);
|
|
213
213
|
if (!webshop) {
|
|
214
214
|
// ignore for now
|
|
215
|
-
console.error(
|
|
216
|
-
return
|
|
215
|
+
console.error('Missing webshop with id ' + this.webshopId + ' in webshop stock queue for order ' + this.id);
|
|
216
|
+
return;
|
|
217
217
|
}
|
|
218
|
-
|
|
219
|
-
await this.setRelation(Order.webshop, webshop).updateStock() // remove reserved stock
|
|
220
|
-
return webshop
|
|
221
|
-
})
|
|
218
|
+
|
|
219
|
+
await this.setRelation(Order.webshop, webshop).updateStock(); // remove reserved stock
|
|
220
|
+
return webshop;
|
|
221
|
+
});
|
|
222
222
|
|
|
223
223
|
if (webshop) {
|
|
224
|
-
await this.setRelation(Order.webshop, webshop).updateTickets()
|
|
224
|
+
await this.setRelation(Order.webshop, webshop).updateTickets();
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
// Send an email if the payment failed after 15 minutes being pending
|
|
@@ -246,12 +246,11 @@ export class Order extends Model {
|
|
|
246
246
|
// } else {
|
|
247
247
|
// console.log('Marked order '+this.id+' as payment failed after ' + (difference / 1000 / 60).toFixed(1) + ' mins. Not sending email.')
|
|
248
248
|
// }
|
|
249
|
-
} else {
|
|
250
|
-
this.markUpdated()
|
|
251
|
-
await this.save()
|
|
252
249
|
}
|
|
253
|
-
|
|
254
|
-
|
|
250
|
+
else {
|
|
251
|
+
this.markUpdated();
|
|
252
|
+
await this.save();
|
|
253
|
+
}
|
|
255
254
|
}
|
|
256
255
|
|
|
257
256
|
/**
|
|
@@ -264,45 +263,45 @@ export class Order extends Model {
|
|
|
264
263
|
// Previous data?
|
|
265
264
|
|
|
266
265
|
// Add or delete this order from the stock?
|
|
267
|
-
const add = this.shouldIncludeStock()
|
|
266
|
+
const add = this.shouldIncludeStock();
|
|
268
267
|
|
|
269
|
-
let changed = false
|
|
270
|
-
const discountCodeUsageMap:
|
|
268
|
+
let changed = false;
|
|
269
|
+
const discountCodeUsageMap: Map<string, number> = new Map();
|
|
271
270
|
|
|
272
271
|
if (previousData !== null) {
|
|
273
272
|
// Remove stock from old items without modifying old data
|
|
274
273
|
for (const item of previousData.cart.items) {
|
|
275
|
-
const product = this.webshop.products.find(p => p.id === item.product.id)
|
|
274
|
+
const product = this.webshop.products.find(p => p.id === item.product.id);
|
|
276
275
|
if (product) {
|
|
277
276
|
if (item.reservedAmount > 0) {
|
|
278
|
-
product.usedStock -= item.reservedAmount
|
|
277
|
+
product.usedStock -= item.reservedAmount;
|
|
279
278
|
if (product.usedStock < 0) {
|
|
280
|
-
product.usedStock = 0
|
|
279
|
+
product.usedStock = 0;
|
|
281
280
|
}
|
|
282
|
-
changed = true
|
|
281
|
+
changed = true;
|
|
283
282
|
}
|
|
284
283
|
|
|
285
284
|
// Product price
|
|
286
285
|
for (const [priceId, amount] of item.reservedPrices) {
|
|
287
|
-
const productPrice = product.prices.find(p => p.id === priceId)
|
|
286
|
+
const productPrice = product.prices.find(p => p.id === priceId);
|
|
288
287
|
if (productPrice) {
|
|
289
|
-
productPrice.usedStock -= amount
|
|
288
|
+
productPrice.usedStock -= amount;
|
|
290
289
|
if (productPrice.usedStock < 0) {
|
|
291
|
-
productPrice.usedStock = 0
|
|
290
|
+
productPrice.usedStock = 0;
|
|
292
291
|
}
|
|
293
|
-
changed = true
|
|
292
|
+
changed = true;
|
|
294
293
|
}
|
|
295
294
|
}
|
|
296
295
|
|
|
297
296
|
// Options
|
|
298
297
|
for (const [optionId, amount] of item.reservedOptions) {
|
|
299
|
-
const option = product.optionMenus.flatMap(om => om.options).find(o => o.id === optionId)
|
|
298
|
+
const option = product.optionMenus.flatMap(om => om.options).find(o => o.id === optionId);
|
|
300
299
|
if (option) {
|
|
301
|
-
option.usedStock -= amount
|
|
300
|
+
option.usedStock -= amount;
|
|
302
301
|
if (option.usedStock < 0) {
|
|
303
|
-
option.usedStock = 0
|
|
302
|
+
option.usedStock = 0;
|
|
304
303
|
}
|
|
305
|
-
changed = true
|
|
304
|
+
changed = true;
|
|
306
305
|
}
|
|
307
306
|
}
|
|
308
307
|
|
|
@@ -310,10 +309,10 @@ export class Order extends Model {
|
|
|
310
309
|
if (item.reservedSeats.length > 0) {
|
|
311
310
|
for (const seat of item.reservedSeats) {
|
|
312
311
|
// Only remove each seat once
|
|
313
|
-
const reservedIndex = product.reservedSeats.findIndex(s => s.equals(seat))
|
|
312
|
+
const reservedIndex = product.reservedSeats.findIndex(s => s.equals(seat));
|
|
314
313
|
if (reservedIndex !== -1) {
|
|
315
|
-
product.reservedSeats.splice(reservedIndex, 1)
|
|
316
|
-
changed = true
|
|
314
|
+
product.reservedSeats.splice(reservedIndex, 1);
|
|
315
|
+
changed = true;
|
|
317
316
|
}
|
|
318
317
|
}
|
|
319
318
|
item.reservedSeats = [];
|
|
@@ -325,7 +324,7 @@ export class Order extends Model {
|
|
|
325
324
|
if (code.reserved) {
|
|
326
325
|
// Remove usage
|
|
327
326
|
code.reserved = false;
|
|
328
|
-
discountCodeUsageMap.set(code.id, (discountCodeUsageMap.get(code.id) ?? 0) - 1)
|
|
327
|
+
discountCodeUsageMap.set(code.id, (discountCodeUsageMap.get(code.id) ?? 0) - 1);
|
|
329
328
|
}
|
|
330
329
|
}
|
|
331
330
|
}
|
|
@@ -333,47 +332,47 @@ export class Order extends Model {
|
|
|
333
332
|
for (const item of this.data.cart.items) {
|
|
334
333
|
if (previousData !== null) {
|
|
335
334
|
// If we have previousData, we already removed the stock from the old items, so reservedAmount is always zero
|
|
336
|
-
item.reservedAmount = 0
|
|
337
|
-
item.reservedPrices = new Map()
|
|
338
|
-
item.reservedOptions = new Map()
|
|
339
|
-
changed = true
|
|
335
|
+
item.reservedAmount = 0;
|
|
336
|
+
item.reservedPrices = new Map();
|
|
337
|
+
item.reservedOptions = new Map();
|
|
338
|
+
changed = true;
|
|
340
339
|
}
|
|
341
340
|
|
|
342
|
-
const difference = add ? (item.amount - item.reservedAmount) : -item.reservedAmount
|
|
341
|
+
const difference = add ? (item.amount - item.reservedAmount) : -item.reservedAmount;
|
|
343
342
|
if (difference !== 0) {
|
|
344
|
-
const product = this.webshop.products.find(p => p.id === item.product.id)
|
|
343
|
+
const product = this.webshop.products.find(p => p.id === item.product.id);
|
|
345
344
|
if (product) {
|
|
346
|
-
product.usedStock += difference
|
|
345
|
+
product.usedStock += difference;
|
|
347
346
|
if (product.usedStock < 0) {
|
|
348
|
-
product.usedStock = 0
|
|
347
|
+
product.usedStock = 0;
|
|
349
348
|
}
|
|
350
349
|
|
|
351
350
|
// Keep track that we included this order in the stock already
|
|
352
|
-
item.reservedAmount += difference
|
|
353
|
-
changed = true
|
|
351
|
+
item.reservedAmount += difference;
|
|
352
|
+
changed = true;
|
|
354
353
|
|
|
355
|
-
const productPrice = product.prices.find(p => p.id === item.productPrice.id)
|
|
354
|
+
const productPrice = product.prices.find(p => p.id === item.productPrice.id);
|
|
356
355
|
if (productPrice) {
|
|
357
|
-
productPrice.usedStock += difference
|
|
356
|
+
productPrice.usedStock += difference;
|
|
358
357
|
if (productPrice.usedStock < 0) {
|
|
359
|
-
productPrice.usedStock = 0
|
|
358
|
+
productPrice.usedStock = 0;
|
|
360
359
|
}
|
|
361
360
|
|
|
362
361
|
// Keep track that we included this order in the stock already
|
|
363
|
-
item.reservedPrices.set(productPrice.id, (item.reservedPrices.get(productPrice.id) ?? 0) + difference)
|
|
362
|
+
item.reservedPrices.set(productPrice.id, (item.reservedPrices.get(productPrice.id) ?? 0) + difference);
|
|
364
363
|
}
|
|
365
364
|
|
|
366
365
|
// Options
|
|
367
366
|
for (const cartItemOption of item.options) {
|
|
368
|
-
const option = product.optionMenus.find(om => om.id === cartItemOption.optionMenu.id)?.options.find(o => o.id === cartItemOption.option.id)
|
|
367
|
+
const option = product.optionMenus.find(om => om.id === cartItemOption.optionMenu.id)?.options.find(o => o.id === cartItemOption.option.id);
|
|
369
368
|
if (option) {
|
|
370
|
-
option.usedStock += difference
|
|
369
|
+
option.usedStock += difference;
|
|
371
370
|
if (option.usedStock < 0) {
|
|
372
|
-
option.usedStock = 0
|
|
371
|
+
option.usedStock = 0;
|
|
373
372
|
}
|
|
374
373
|
|
|
375
374
|
// Keep track that we included this order in the stock already
|
|
376
|
-
item.reservedOptions.set(option.id, (item.reservedOptions.get(option.id) ?? 0) + difference)
|
|
375
|
+
item.reservedOptions.set(option.id, (item.reservedOptions.get(option.id) ?? 0) + difference);
|
|
377
376
|
}
|
|
378
377
|
}
|
|
379
378
|
}
|
|
@@ -382,58 +381,60 @@ export class Order extends Model {
|
|
|
382
381
|
|
|
383
382
|
if (previousData !== null && previousData.timeSlot) {
|
|
384
383
|
// Changed timeslot. Remove all reserved ones
|
|
385
|
-
const ps = previousData.timeSlot
|
|
386
|
-
const timeSlot = this.webshop.meta.checkoutMethods.flatMap(m => m.timeSlots).flatMap(t => t.timeSlots).find(t => t.id === ps.id)
|
|
384
|
+
const ps = previousData.timeSlot;
|
|
385
|
+
const timeSlot = this.webshop.meta.checkoutMethods.flatMap(m => m.timeSlots).flatMap(t => t.timeSlots).find(t => t.id === ps.id);
|
|
387
386
|
if (timeSlot) {
|
|
388
387
|
// Remove any reserved stock
|
|
389
|
-
const updated = Order.updateTimeSlotStock(timeSlot, this.data, false)
|
|
390
|
-
changed = changed || updated
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
this.data.
|
|
394
|
-
|
|
388
|
+
const updated = Order.updateTimeSlotStock(timeSlot, this.data, false);
|
|
389
|
+
changed = changed || updated;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
this.data.reservedOrder = false;
|
|
393
|
+
this.data.reservedPersons = 0;
|
|
394
|
+
changed = true;
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
|
|
398
398
|
if (this.data.timeSlot !== null) {
|
|
399
|
-
const s = this.data.timeSlot
|
|
400
|
-
const timeSlot = this.webshop.meta.checkoutMethods.flatMap(m => m.timeSlots).flatMap(t => t.timeSlots).find(t => t.id === s.id)
|
|
399
|
+
const s = this.data.timeSlot;
|
|
400
|
+
const timeSlot = this.webshop.meta.checkoutMethods.flatMap(m => m.timeSlots).flatMap(t => t.timeSlots).find(t => t.id === s.id);
|
|
401
401
|
|
|
402
402
|
if (timeSlot) {
|
|
403
|
-
const updated = Order.updateTimeSlotStock(timeSlot, this.data, add)
|
|
404
|
-
changed = changed || updated
|
|
405
|
-
}
|
|
406
|
-
|
|
403
|
+
const updated = Order.updateTimeSlotStock(timeSlot, this.data, add);
|
|
404
|
+
changed = changed || updated;
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
console.error('Missing timeslot ' + s.id + ' in webshop ' + this.webshopId);
|
|
407
408
|
}
|
|
408
409
|
}
|
|
409
410
|
|
|
410
411
|
// Seats
|
|
411
412
|
for (const item of this.data.cart.items) {
|
|
412
413
|
if (item.seats.length > 0) {
|
|
413
|
-
const product = this.webshop.products.find(p => p.id === item.product.id)
|
|
414
|
+
const product = this.webshop.products.find(p => p.id === item.product.id);
|
|
414
415
|
if (product) {
|
|
415
416
|
if (previousData !== null) {
|
|
416
417
|
// Already removed
|
|
417
|
-
item.reservedSeats = []
|
|
418
|
-
changed = true
|
|
418
|
+
item.reservedSeats = [];
|
|
419
|
+
changed = true;
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
// First remove all (but only once!), to avoid duplicates
|
|
422
423
|
for (const seat of item.reservedSeats) {
|
|
423
|
-
const reservedIndex = product.reservedSeats.findIndex(s => s.equals(seat))
|
|
424
|
+
const reservedIndex = product.reservedSeats.findIndex(s => s.equals(seat));
|
|
424
425
|
if (reservedIndex !== -1) {
|
|
425
|
-
product.reservedSeats.splice(reservedIndex, 1)
|
|
426
|
+
product.reservedSeats.splice(reservedIndex, 1);
|
|
426
427
|
}
|
|
427
428
|
}
|
|
428
429
|
|
|
429
430
|
// First remove all (but only once!), to avoid duplicates
|
|
430
431
|
if (add) {
|
|
431
432
|
for (const seat of item.seats) {
|
|
432
|
-
product.reservedSeats.push(seat)
|
|
433
|
+
product.reservedSeats.push(seat);
|
|
433
434
|
}
|
|
434
435
|
}
|
|
435
|
-
changed = true
|
|
436
|
-
item.reservedSeats = add ? item.seats : []
|
|
436
|
+
changed = true;
|
|
437
|
+
item.reservedSeats = add ? item.seats : [];
|
|
437
438
|
}
|
|
438
439
|
}
|
|
439
440
|
}
|
|
@@ -442,18 +443,19 @@ export class Order extends Model {
|
|
|
442
443
|
for (const code of this.data.discountCodes) {
|
|
443
444
|
if (previousData !== null) {
|
|
444
445
|
code.reserved = false;
|
|
445
|
-
changed = true
|
|
446
|
+
changed = true;
|
|
446
447
|
}
|
|
447
448
|
|
|
448
449
|
if (code.reserved && !add) {
|
|
449
450
|
// Remove usage
|
|
450
451
|
code.reserved = false;
|
|
451
|
-
discountCodeUsageMap.set(code.id, (discountCodeUsageMap.get(code.id) ?? 0) - 1)
|
|
452
|
-
changed = true
|
|
453
|
-
}
|
|
452
|
+
discountCodeUsageMap.set(code.id, (discountCodeUsageMap.get(code.id) ?? 0) - 1);
|
|
453
|
+
changed = true;
|
|
454
|
+
}
|
|
455
|
+
else if (!code.reserved && add) {
|
|
454
456
|
code.reserved = true;
|
|
455
|
-
discountCodeUsageMap.set(code.id, (discountCodeUsageMap.get(code.id) ?? 0) + 1)
|
|
456
|
-
changed = true
|
|
457
|
+
discountCodeUsageMap.set(code.id, (discountCodeUsageMap.get(code.id) ?? 0) + 1);
|
|
458
|
+
changed = true;
|
|
457
459
|
}
|
|
458
460
|
}
|
|
459
461
|
|
|
@@ -462,50 +464,50 @@ export class Order extends Model {
|
|
|
462
464
|
const code = await WebshopDiscountCode.getByID(id);
|
|
463
465
|
if (code) {
|
|
464
466
|
code.usageCount += amount;
|
|
465
|
-
await code.save()
|
|
466
|
-
changed = true
|
|
467
|
+
await code.save();
|
|
468
|
+
changed = true;
|
|
467
469
|
}
|
|
468
470
|
}
|
|
469
471
|
}
|
|
470
472
|
|
|
471
473
|
if (changed) {
|
|
472
|
-
await this.webshop.save()
|
|
473
|
-
await this.save()
|
|
474
|
+
await this.webshop.save();
|
|
475
|
+
await this.save();
|
|
474
476
|
}
|
|
475
477
|
}
|
|
476
478
|
|
|
477
479
|
private static updateTimeSlotStock(timeSlot: WebshopTimeSlot, data: OrderData, add: boolean) {
|
|
478
|
-
let changed = false
|
|
480
|
+
let changed = false;
|
|
479
481
|
if (data.reservedOrder !== add) {
|
|
480
|
-
data.reservedOrder = add
|
|
481
|
-
timeSlot.usedOrders += add ? 1 : -1
|
|
482
|
+
data.reservedOrder = add;
|
|
483
|
+
timeSlot.usedOrders += add ? 1 : -1;
|
|
482
484
|
if (timeSlot.usedOrders < 0) {
|
|
483
|
-
timeSlot.usedOrders = 0
|
|
485
|
+
timeSlot.usedOrders = 0;
|
|
484
486
|
}
|
|
485
|
-
changed = true
|
|
487
|
+
changed = true;
|
|
486
488
|
}
|
|
487
489
|
|
|
488
|
-
const personDifference = (add ? data.cart.persons : 0) - data.reservedPersons
|
|
490
|
+
const personDifference = (add ? data.cart.persons : 0) - data.reservedPersons;
|
|
489
491
|
|
|
490
492
|
if (personDifference !== 0) {
|
|
491
|
-
timeSlot.usedPersons += personDifference
|
|
493
|
+
timeSlot.usedPersons += personDifference;
|
|
492
494
|
if (timeSlot.usedPersons < 0) {
|
|
493
|
-
timeSlot.usedPersons = 0
|
|
495
|
+
timeSlot.usedPersons = 0;
|
|
494
496
|
}
|
|
495
|
-
data.reservedPersons += personDifference
|
|
496
|
-
changed = true
|
|
497
|
+
data.reservedPersons += personDifference;
|
|
498
|
+
changed = true;
|
|
497
499
|
}
|
|
498
|
-
return changed
|
|
500
|
+
return changed;
|
|
499
501
|
}
|
|
500
502
|
|
|
501
|
-
async updateTickets(this: Order & { webshop: Webshop }): Promise<{ tickets: Ticket[]
|
|
502
|
-
const webshop = this.webshop
|
|
503
|
+
async updateTickets(this: Order & { webshop: Webshop }): Promise<{ tickets: Ticket[]; didCreateTickets: boolean }> {
|
|
504
|
+
const webshop = this.webshop;
|
|
503
505
|
|
|
504
506
|
if (webshop.meta.ticketType !== WebshopTicketType.Tickets && webshop.meta.ticketType !== WebshopTicketType.SingleTicket) {
|
|
505
507
|
return { tickets: [], didCreateTickets: false };
|
|
506
508
|
}
|
|
507
509
|
|
|
508
|
-
const existingTickets = !this.id ? [] : await Ticket.where({ orderId: this.id })
|
|
510
|
+
const existingTickets = !this.id ? [] : await Ticket.where({ orderId: this.id });
|
|
509
511
|
|
|
510
512
|
if (!(await this.shouldCreateTickets())) {
|
|
511
513
|
// Delete all existing tickets
|
|
@@ -513,99 +515,100 @@ export class Order extends Model {
|
|
|
513
515
|
if (ticket.isDeleted) {
|
|
514
516
|
continue;
|
|
515
517
|
}
|
|
516
|
-
console.log(
|
|
518
|
+
console.log('Deleting ticket for order ' + this.id + ', ticket id = ' + ticket.id);
|
|
517
519
|
await ticket.softDelete();
|
|
518
520
|
}
|
|
519
|
-
return { tickets: [], didCreateTickets: false }
|
|
521
|
+
return { tickets: [], didCreateTickets: false };
|
|
520
522
|
}
|
|
521
523
|
|
|
522
524
|
// Create tickets if needed (we might already be valid in case of transfer payments)
|
|
523
|
-
let tickets: Ticket[] = []
|
|
525
|
+
let tickets: Ticket[] = [];
|
|
524
526
|
|
|
525
527
|
if (webshop.meta.ticketType === WebshopTicketType.Tickets) {
|
|
526
|
-
const ticketMap = new Map<string, number>()
|
|
528
|
+
const ticketMap = new Map<string, number>();
|
|
527
529
|
|
|
528
530
|
for (const item of this.data.cart.items) {
|
|
529
531
|
if (item.product.type === ProductType.Ticket || item.product.type === ProductType.Voucher) {
|
|
530
|
-
const offset = ticketMap.get(item.product.id) ?? 0
|
|
532
|
+
const offset = ticketMap.get(item.product.id) ?? 0;
|
|
531
533
|
|
|
532
534
|
// Separate ticket if multiple amounts
|
|
533
535
|
for (let index = 0; index < item.amount; index++) {
|
|
534
|
-
const ticket = new Ticket()
|
|
535
|
-
ticket.orderId = this.id
|
|
536
|
-
ticket.itemId = item.id
|
|
537
|
-
ticket.organizationId = this.organizationId
|
|
538
|
-
ticket.webshopId = this.webshopId
|
|
536
|
+
const ticket = new Ticket();
|
|
537
|
+
ticket.orderId = this.id;
|
|
538
|
+
ticket.itemId = item.id;
|
|
539
|
+
ticket.organizationId = this.organizationId;
|
|
540
|
+
ticket.webshopId = this.webshopId;
|
|
539
541
|
|
|
540
542
|
// Relative index for items with same properties
|
|
541
|
-
ticket.index = offset + index + 1
|
|
542
|
-
ticket.total = item.getTotalAmount(this.data.cart)
|
|
543
|
+
ticket.index = offset + index + 1;
|
|
544
|
+
ticket.total = item.getTotalAmount(this.data.cart);
|
|
543
545
|
|
|
544
546
|
// Seat
|
|
545
|
-
ticket.seat = item.seats.length > 0 ? item.seats[index] : null
|
|
546
|
-
ticket.originalSeat = ticket.seat
|
|
547
|
+
ticket.seat = item.seats.length > 0 ? item.seats[index] : null;
|
|
548
|
+
ticket.originalSeat = ticket.seat;
|
|
547
549
|
|
|
548
550
|
// Do not save yet
|
|
549
|
-
tickets.push(ticket)
|
|
551
|
+
tickets.push(ticket);
|
|
550
552
|
}
|
|
551
553
|
|
|
552
|
-
ticketMap.set(item.product.id, offset + item.amount)
|
|
554
|
+
ticketMap.set(item.product.id, offset + item.amount);
|
|
553
555
|
}
|
|
554
556
|
}
|
|
555
|
-
}
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
556
559
|
// Create a shared ticket for the whole order
|
|
557
|
-
const ticket = new Ticket()
|
|
558
|
-
ticket.orderId = this.id
|
|
559
|
-
ticket.itemId = null
|
|
560
|
-
ticket.organizationId = this.organizationId
|
|
561
|
-
ticket.webshopId = this.webshopId
|
|
560
|
+
const ticket = new Ticket();
|
|
561
|
+
ticket.orderId = this.id;
|
|
562
|
+
ticket.itemId = null;
|
|
563
|
+
ticket.organizationId = this.organizationId;
|
|
564
|
+
ticket.webshopId = this.webshopId;
|
|
562
565
|
|
|
563
566
|
// Relative index for items with same properties
|
|
564
|
-
ticket.index = 1
|
|
565
|
-
ticket.total = 1
|
|
567
|
+
ticket.index = 1;
|
|
568
|
+
ticket.total = 1;
|
|
566
569
|
|
|
567
570
|
// Do not save yet
|
|
568
|
-
tickets.push(ticket)
|
|
571
|
+
tickets.push(ticket);
|
|
569
572
|
}
|
|
570
573
|
|
|
571
|
-
let didCreateTickets = false
|
|
574
|
+
let didCreateTickets = false;
|
|
572
575
|
|
|
573
576
|
if (!this.id) {
|
|
574
|
-
await this.save()
|
|
577
|
+
await this.save();
|
|
575
578
|
for (const ticket of tickets) {
|
|
576
|
-
ticket.orderId = this.id
|
|
579
|
+
ticket.orderId = this.id;
|
|
577
580
|
}
|
|
578
581
|
}
|
|
579
582
|
|
|
580
583
|
// First check if we already have tickets
|
|
581
|
-
const mergedTickets: Ticket[] = []
|
|
582
|
-
|
|
584
|
+
const mergedTickets: Ticket[] = [];
|
|
585
|
+
|
|
583
586
|
// First try to keep existing tickets
|
|
584
587
|
for (const existing of existingTickets) {
|
|
585
588
|
if (existing.originalSeat) {
|
|
586
|
-
const index = tickets.findIndex(t => t.seat && t.seat.equals(existing.originalSeat!))
|
|
589
|
+
const index = tickets.findIndex(t => t.seat && t.seat.equals(existing.originalSeat!));
|
|
587
590
|
if (index !== -1) {
|
|
588
|
-
const ticket = tickets[index]
|
|
591
|
+
const ticket = tickets[index];
|
|
589
592
|
tickets.splice(index, 1);
|
|
590
593
|
existing.itemId = ticket.itemId;
|
|
591
594
|
existing.index = ticket.index;
|
|
592
|
-
existing.total = ticket.total
|
|
593
|
-
existing.seat = ticket.seat
|
|
594
|
-
existing.deletedAt =
|
|
595
|
-
mergedTickets.push(existing)
|
|
595
|
+
existing.total = ticket.total;
|
|
596
|
+
existing.seat = ticket.seat;
|
|
597
|
+
existing.deletedAt = null;
|
|
598
|
+
mergedTickets.push(existing);
|
|
596
599
|
}
|
|
597
600
|
continue;
|
|
598
601
|
}
|
|
599
|
-
const index = tickets.findIndex(ticket => existing.itemId === ticket.itemId && ticket.index === existing.index)
|
|
602
|
+
const index = tickets.findIndex(ticket => existing.itemId === ticket.itemId && ticket.index === existing.index);
|
|
600
603
|
if (index !== -1) {
|
|
601
|
-
const ticket = tickets[index]
|
|
604
|
+
const ticket = tickets[index];
|
|
602
605
|
tickets.splice(index, 1);
|
|
603
606
|
existing.itemId = ticket.itemId;
|
|
604
607
|
existing.index = ticket.index;
|
|
605
|
-
existing.total = ticket.total
|
|
606
|
-
existing.seat = ticket.seat
|
|
607
|
-
existing.deletedAt =
|
|
608
|
-
mergedTickets.push(existing)
|
|
608
|
+
existing.total = ticket.total;
|
|
609
|
+
existing.seat = ticket.seat;
|
|
610
|
+
existing.deletedAt = null;
|
|
611
|
+
mergedTickets.push(existing);
|
|
609
612
|
}
|
|
610
613
|
}
|
|
611
614
|
|
|
@@ -615,31 +618,31 @@ export class Order extends Model {
|
|
|
615
618
|
// Already mapped
|
|
616
619
|
continue;
|
|
617
620
|
}
|
|
618
|
-
|
|
619
|
-
const index = tickets.findIndex(ticket => existing.itemId === ticket.itemId)
|
|
621
|
+
|
|
622
|
+
const index = tickets.findIndex(ticket => existing.itemId === ticket.itemId);
|
|
620
623
|
if (index !== -1) {
|
|
621
|
-
const ticket = tickets[index]
|
|
624
|
+
const ticket = tickets[index];
|
|
622
625
|
tickets.splice(index, 1);
|
|
623
626
|
existing.itemId = ticket.itemId;
|
|
624
627
|
existing.index = ticket.index;
|
|
625
|
-
existing.total = ticket.total
|
|
626
|
-
existing.seat = ticket.seat
|
|
627
|
-
existing.deletedAt =
|
|
628
|
-
mergedTickets.push(existing)
|
|
628
|
+
existing.total = ticket.total;
|
|
629
|
+
existing.seat = ticket.seat;
|
|
630
|
+
existing.deletedAt = null;
|
|
631
|
+
mergedTickets.push(existing);
|
|
629
632
|
}
|
|
630
633
|
}
|
|
631
|
-
|
|
634
|
+
|
|
632
635
|
// Remaining tickets that were not reused
|
|
633
636
|
for (const ticket of tickets) {
|
|
634
|
-
didCreateTickets = true
|
|
635
|
-
mergedTickets.push(ticket)
|
|
637
|
+
didCreateTickets = true;
|
|
638
|
+
mergedTickets.push(ticket);
|
|
636
639
|
}
|
|
637
640
|
|
|
638
|
-
tickets = mergedTickets
|
|
641
|
+
tickets = mergedTickets;
|
|
639
642
|
|
|
640
643
|
// Wait to save them all
|
|
641
|
-
console.log(
|
|
642
|
-
await Promise.all(tickets.map(
|
|
644
|
+
console.log('Saving merged tickets for order ' + this.id);
|
|
645
|
+
await Promise.all(tickets.map(ticket => ticket.save()));
|
|
643
646
|
|
|
644
647
|
// Delete others
|
|
645
648
|
for (const existing of existingTickets) {
|
|
@@ -647,104 +650,106 @@ export class Order extends Model {
|
|
|
647
650
|
if (existing.isDeleted) {
|
|
648
651
|
continue;
|
|
649
652
|
}
|
|
650
|
-
console.log(
|
|
651
|
-
await existing.softDelete()
|
|
653
|
+
console.log('Deleting ticket for order ' + this.id + ', ticket id = ' + existing.id);
|
|
654
|
+
await existing.softDelete();
|
|
652
655
|
}
|
|
653
656
|
}
|
|
654
657
|
|
|
655
|
-
return { tickets, didCreateTickets }
|
|
658
|
+
return { tickets, didCreateTickets };
|
|
656
659
|
}
|
|
657
660
|
|
|
658
661
|
markUpdated() {
|
|
659
|
-
this.updatedAt = new Date()
|
|
662
|
+
this.updatedAt = new Date();
|
|
660
663
|
|
|
661
664
|
// Also save if this is the only saved property
|
|
662
|
-
this.forceSaveProperty(
|
|
665
|
+
this.forceSaveProperty('updatedAt');
|
|
663
666
|
}
|
|
664
667
|
|
|
665
668
|
/**
|
|
666
669
|
* A payment changed the total paid amount
|
|
667
670
|
*/
|
|
668
671
|
async paymentChanged(this: Order, payment: Payment | null, organization: Organization, knownWebshop?: Webshop) {
|
|
669
|
-
this.markUpdated()
|
|
670
|
-
await this.save()
|
|
672
|
+
this.markUpdated();
|
|
673
|
+
await this.save();
|
|
671
674
|
}
|
|
672
675
|
|
|
673
676
|
async undoPaid(this: Order, payment: Payment | null, organization: Organization, knownWebshop?: Webshop) {
|
|
674
|
-
this.markUpdated()
|
|
675
|
-
await this.save()
|
|
677
|
+
this.markUpdated();
|
|
678
|
+
await this.save();
|
|
676
679
|
|
|
677
680
|
const webshop = (knownWebshop ?? (await Webshop.getByID(this.webshopId)))?.setRelation(Webshop.organization, organization);
|
|
678
681
|
if (!webshop) {
|
|
679
|
-
console.error(
|
|
680
|
-
return
|
|
682
|
+
console.error('Missing webshop for order ' + this.id);
|
|
683
|
+
return;
|
|
681
684
|
}
|
|
682
|
-
|
|
683
|
-
await this.setRelation(Order.webshop, webshop).updateTickets()
|
|
685
|
+
|
|
686
|
+
await this.setRelation(Order.webshop, webshop).updateTickets();
|
|
684
687
|
}
|
|
685
688
|
|
|
686
689
|
/**
|
|
687
690
|
* Only call this once! Make sure you use the queues correctly
|
|
688
691
|
*/
|
|
689
692
|
async markPaid(this: Order, payment: Payment | null, organization: Organization, knownWebshop?: Webshop) {
|
|
690
|
-
console.log(
|
|
691
|
-
this.markUpdated()
|
|
692
|
-
await this.save()
|
|
693
|
+
console.log('Marking order ' + this.id + ' as paid');
|
|
694
|
+
this.markUpdated();
|
|
695
|
+
await this.save();
|
|
693
696
|
const webshop = (knownWebshop ?? (await Webshop.getByID(this.webshopId)))?.setRelation(Webshop.organization, organization);
|
|
694
697
|
if (!webshop) {
|
|
695
|
-
console.error(
|
|
696
|
-
return
|
|
698
|
+
console.error('Missing webshop for order ' + this.id);
|
|
699
|
+
return;
|
|
697
700
|
}
|
|
698
701
|
|
|
699
702
|
if (this.status === OrderStatus.Deleted) {
|
|
700
|
-
await this.undoPaymentFailed(payment, organization)
|
|
703
|
+
await this.undoPaymentFailed(payment, organization);
|
|
701
704
|
}
|
|
702
705
|
|
|
703
|
-
const { tickets, didCreateTickets } = await this.setRelation(Order.webshop, webshop).updateTickets()
|
|
706
|
+
const { tickets, didCreateTickets } = await this.setRelation(Order.webshop, webshop).updateTickets();
|
|
704
707
|
|
|
705
708
|
// Needs to happen before validation, because we can include the tickets in the validation that way
|
|
706
709
|
if (this.validAt === null) {
|
|
707
|
-
await this.setRelation(Order.webshop, webshop).markValid(payment, tickets)
|
|
708
|
-
}
|
|
710
|
+
await this.setRelation(Order.webshop, webshop).markValid(payment, tickets);
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
709
713
|
if (!this.data.shouldSendPaymentUpdates) {
|
|
710
|
-
console.log(
|
|
711
|
-
return
|
|
714
|
+
console.log('Skip sending paid email for order ' + this.id);
|
|
715
|
+
return;
|
|
712
716
|
}
|
|
713
|
-
if (this.data.customer.email.length > 0){
|
|
717
|
+
if (this.data.customer.email.length > 0) {
|
|
714
718
|
if (didCreateTickets) {
|
|
715
|
-
await this.setRelation(Order.webshop, webshop).sendTickets()
|
|
716
|
-
}
|
|
719
|
+
await this.setRelation(Order.webshop, webshop).sendTickets();
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
717
722
|
if (payment && payment.method === PaymentMethod.Transfer) {
|
|
718
|
-
await this.setRelation(Order.webshop, webshop).sendPaidMail()
|
|
723
|
+
await this.setRelation(Order.webshop, webshop).sendPaidMail();
|
|
719
724
|
}
|
|
720
725
|
}
|
|
721
726
|
}
|
|
722
727
|
}
|
|
723
728
|
}
|
|
724
729
|
|
|
725
|
-
async sendPaidMail(this: Order & { webshop: Webshop & { organization: Organization } }) {
|
|
726
|
-
const organization = this.webshop.organization
|
|
727
|
-
const { from, replyTo } = organization.getEmail(this.webshop.privateMeta.defaultEmailId, true)
|
|
730
|
+
async sendPaidMail(this: Order & { webshop: Webshop & { organization: Organization } }) {
|
|
731
|
+
const organization = this.webshop.organization;
|
|
732
|
+
const { from, replyTo } = organization.getEmail(this.webshop.privateMeta.defaultEmailId, true);
|
|
728
733
|
|
|
729
734
|
await this.sendEmailTemplate({
|
|
730
735
|
type: EmailTemplateType.OrderReceivedTransfer,
|
|
731
736
|
from,
|
|
732
|
-
replyTo
|
|
733
|
-
})
|
|
737
|
+
replyTo,
|
|
738
|
+
});
|
|
734
739
|
}
|
|
735
740
|
|
|
736
|
-
async sendTickets(this: Order & { webshop: Webshop & { organization: Organization } }) {
|
|
737
|
-
const organization = this.webshop.organization
|
|
738
|
-
const { from, replyTo } = organization.getEmail(this.webshop.privateMeta.defaultEmailId, true)
|
|
741
|
+
async sendTickets(this: Order & { webshop: Webshop & { organization: Organization } }) {
|
|
742
|
+
const organization = this.webshop.organization;
|
|
743
|
+
const { from, replyTo } = organization.getEmail(this.webshop.privateMeta.defaultEmailId, true);
|
|
739
744
|
|
|
740
745
|
await this.sendEmailTemplate({
|
|
741
746
|
type: EmailTemplateType.TicketsReceivedTransfer,
|
|
742
747
|
from,
|
|
743
|
-
replyTo
|
|
744
|
-
})
|
|
748
|
+
replyTo,
|
|
749
|
+
});
|
|
745
750
|
}
|
|
746
751
|
|
|
747
|
-
getStructureWithoutPayment()
|
|
752
|
+
getStructureWithoutPayment() {
|
|
748
753
|
return OrderStruct.create({
|
|
749
754
|
id: this.id,
|
|
750
755
|
webshopId: this.webshopId,
|
|
@@ -760,118 +765,117 @@ export class Order extends Model {
|
|
|
760
765
|
|
|
761
766
|
static async getStructures(orders: Order[]): Promise<OrderStruct[]> {
|
|
762
767
|
if (orders.length === 0) {
|
|
763
|
-
return []
|
|
768
|
+
return [];
|
|
764
769
|
}
|
|
765
770
|
|
|
766
771
|
// Balance items
|
|
767
772
|
const allBalanceItems = await BalanceItem.where({ orderId: {
|
|
768
|
-
sign:
|
|
769
|
-
value: orders.map(o => o.id)
|
|
770
|
-
} })
|
|
773
|
+
sign: 'IN',
|
|
774
|
+
value: orders.map(o => o.id),
|
|
775
|
+
} });
|
|
771
776
|
|
|
772
|
-
const {payments, balanceItemPayments} = await BalanceItem.loadPayments(allBalanceItems)
|
|
777
|
+
const { payments, balanceItemPayments } = await BalanceItem.loadPayments(allBalanceItems);
|
|
773
778
|
|
|
774
|
-
const structures: OrderStruct[] = []
|
|
779
|
+
const structures: OrderStruct[] = [];
|
|
775
780
|
for (const order of orders) {
|
|
776
|
-
const balanceItems = allBalanceItems.filter(b => b.orderId === order.id)
|
|
781
|
+
const balanceItems = allBalanceItems.filter(b => b.orderId === order.id);
|
|
777
782
|
|
|
778
783
|
const balanceItemStructures = balanceItems.map((balanceItem) => {
|
|
779
784
|
return BalanceItemWithPayments.create({
|
|
780
785
|
...balanceItem,
|
|
781
|
-
payments: balanceItemPayments.filter(b => b.balanceItemId === balanceItem.id).map(balanceItemPayment => {
|
|
782
|
-
const payment = payments.find(pp => pp.id === balanceItemPayment.paymentId)
|
|
786
|
+
payments: balanceItemPayments.filter(b => b.balanceItemId === balanceItem.id).map((balanceItemPayment) => {
|
|
787
|
+
const payment = payments.find(pp => pp.id === balanceItemPayment.paymentId)!;
|
|
783
788
|
return BalanceItemPaymentWithPayment.create({
|
|
784
789
|
...balanceItemPayment,
|
|
785
|
-
payment: PaymentStruct.create(payment)
|
|
786
|
-
})
|
|
787
|
-
})
|
|
790
|
+
payment: PaymentStruct.create(payment),
|
|
791
|
+
});
|
|
792
|
+
}),
|
|
788
793
|
});
|
|
789
|
-
})
|
|
794
|
+
});
|
|
790
795
|
|
|
791
796
|
structures.push(
|
|
792
797
|
OrderStruct.create({
|
|
793
798
|
...order,
|
|
794
799
|
balanceItems: balanceItemStructures,
|
|
795
800
|
// Compatibility
|
|
796
|
-
payment: balanceItemStructures[0]?.payments[0]?.payment ?? null
|
|
797
|
-
})
|
|
798
|
-
)
|
|
801
|
+
payment: balanceItemStructures[0]?.payments[0]?.payment ?? null,
|
|
802
|
+
}),
|
|
803
|
+
);
|
|
799
804
|
}
|
|
800
805
|
|
|
801
|
-
return structures
|
|
806
|
+
return structures;
|
|
802
807
|
}
|
|
803
808
|
|
|
804
809
|
static async getPrivateStructures(orders: Order[]): Promise<PrivateOrder[]> {
|
|
805
810
|
if (orders.length === 0) {
|
|
806
|
-
return []
|
|
811
|
+
return [];
|
|
807
812
|
}
|
|
808
813
|
|
|
809
814
|
// Balance items
|
|
810
815
|
const allBalanceItems = await BalanceItem.where({ orderId: {
|
|
811
|
-
sign:
|
|
812
|
-
value: orders.map(o => o.id)
|
|
813
|
-
} })
|
|
816
|
+
sign: 'IN',
|
|
817
|
+
value: orders.map(o => o.id),
|
|
818
|
+
} });
|
|
814
819
|
|
|
815
|
-
const {payments, balanceItemPayments} = await BalanceItem.loadPayments(allBalanceItems)
|
|
820
|
+
const { payments, balanceItemPayments } = await BalanceItem.loadPayments(allBalanceItems);
|
|
816
821
|
|
|
817
|
-
const structures: PrivateOrder[] = []
|
|
822
|
+
const structures: PrivateOrder[] = [];
|
|
818
823
|
for (const order of orders) {
|
|
819
|
-
const balanceItems = allBalanceItems.filter(b => b.orderId === order.id)
|
|
824
|
+
const balanceItems = allBalanceItems.filter(b => b.orderId === order.id);
|
|
820
825
|
|
|
821
826
|
const balanceItemStructures = balanceItems.map((balanceItem) => {
|
|
822
827
|
return BalanceItemWithPrivatePayments.create({
|
|
823
828
|
...balanceItem,
|
|
824
|
-
payments: balanceItemPayments.filter(b => b.balanceItemId === balanceItem.id).map(balanceItemPayment => {
|
|
825
|
-
const payment = payments.find(pp => pp.id === balanceItemPayment.paymentId)
|
|
829
|
+
payments: balanceItemPayments.filter(b => b.balanceItemId === balanceItem.id).map((balanceItemPayment) => {
|
|
830
|
+
const payment = payments.find(pp => pp.id === balanceItemPayment.paymentId)!;
|
|
826
831
|
return BalanceItemPaymentWithPrivatePayment.create({
|
|
827
832
|
...balanceItemPayment,
|
|
828
|
-
payment: PrivatePayment.create(payment)
|
|
829
|
-
})
|
|
830
|
-
})
|
|
833
|
+
payment: PrivatePayment.create(payment),
|
|
834
|
+
});
|
|
835
|
+
}),
|
|
831
836
|
});
|
|
832
|
-
})
|
|
837
|
+
});
|
|
833
838
|
|
|
834
839
|
structures.push(
|
|
835
840
|
PrivateOrder.create({
|
|
836
841
|
...order,
|
|
837
842
|
balanceItems: balanceItemStructures,
|
|
838
843
|
// Compatibility
|
|
839
|
-
payment: balanceItemStructures[0]?.payments[0]?.payment ?? null
|
|
840
|
-
})
|
|
841
|
-
)
|
|
844
|
+
payment: balanceItemStructures[0]?.payments[0]?.payment ?? null,
|
|
845
|
+
}),
|
|
846
|
+
);
|
|
842
847
|
}
|
|
843
848
|
|
|
844
|
-
return structures
|
|
849
|
+
return structures;
|
|
845
850
|
}
|
|
846
851
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
return (await Order.getStructures([this]))[0]
|
|
852
|
+
async getStructure() {
|
|
853
|
+
return (await Order.getStructures([this]))[0];
|
|
850
854
|
}
|
|
851
855
|
|
|
852
856
|
async sendEmailTemplate(this: Order & { webshop: Webshop & { organization: Organization } }, data: {
|
|
853
|
-
type: EmailTemplateType
|
|
854
|
-
from: string
|
|
855
|
-
replyTo?: string
|
|
856
|
-
to?: Recipient
|
|
857
|
+
type: EmailTemplateType;
|
|
858
|
+
from: string;
|
|
859
|
+
replyTo?: string;
|
|
860
|
+
to?: Recipient;
|
|
857
861
|
}) {
|
|
858
862
|
// Never send an email for archived webshops
|
|
859
863
|
if (this.webshop.meta.status === WebshopStatus.Archived) {
|
|
860
|
-
return
|
|
864
|
+
return;
|
|
861
865
|
}
|
|
862
866
|
|
|
863
867
|
let recipient = (await this.getStructure()).getRecipient(
|
|
864
|
-
this.webshop.organization.getBaseStructure(),
|
|
865
|
-
WebshopPreview.create(this.webshop)
|
|
866
|
-
)
|
|
868
|
+
this.webshop.organization.getBaseStructure(),
|
|
869
|
+
WebshopPreview.create(this.webshop),
|
|
870
|
+
);
|
|
867
871
|
|
|
868
872
|
if (data.to) {
|
|
869
873
|
// Clear first and last name
|
|
870
874
|
recipient.firstName = null;
|
|
871
875
|
recipient.lastName = null;
|
|
872
|
-
recipient.replacements = recipient.replacements.filter(r => !['firstName', 'lastName'].includes(r.token))
|
|
876
|
+
recipient.replacements = recipient.replacements.filter(r => !['firstName', 'lastName'].includes(r.token));
|
|
873
877
|
data.to.merge(recipient);
|
|
874
|
-
recipient = data.to
|
|
878
|
+
recipient = data.to;
|
|
875
879
|
}
|
|
876
880
|
|
|
877
881
|
// Create e-mail builder
|
|
@@ -879,10 +883,10 @@ export class Order extends Model {
|
|
|
879
883
|
recipients: [recipient],
|
|
880
884
|
template: {
|
|
881
885
|
type: data.type,
|
|
882
|
-
webshop: this.webshop
|
|
886
|
+
webshop: this.webshop,
|
|
883
887
|
},
|
|
884
888
|
type: 'transactional',
|
|
885
|
-
})
|
|
889
|
+
});
|
|
886
890
|
}
|
|
887
891
|
|
|
888
892
|
/**
|
|
@@ -890,105 +894,108 @@ export class Order extends Model {
|
|
|
890
894
|
* Include any tickets that are generated and should be included in the e-mail
|
|
891
895
|
*/
|
|
892
896
|
async markValid(this: Order & { webshop: Webshop & { organization: Organization } }, payment: Payment | null, tickets: Ticket[]) {
|
|
893
|
-
const webshop = this.webshop
|
|
894
|
-
const organization = webshop.organization
|
|
897
|
+
const webshop = this.webshop;
|
|
898
|
+
const organization = webshop.organization;
|
|
895
899
|
|
|
896
|
-
console.log(
|
|
897
|
-
const wasValid = this.validAt !== null
|
|
900
|
+
console.log('Marking as valid: order ' + this.id);
|
|
901
|
+
const wasValid = this.validAt !== null;
|
|
898
902
|
|
|
899
903
|
if (wasValid) {
|
|
900
|
-
console.warn(
|
|
901
|
-
return
|
|
904
|
+
console.warn('Warning: already validated an order');
|
|
905
|
+
return;
|
|
902
906
|
}
|
|
903
|
-
this.validAt = new Date() // will get flattened AFTER calculations
|
|
904
|
-
this.validAt.setMilliseconds(0)
|
|
905
|
-
this.number = await WebshopCounter.getNextNumber(this.webshopId, this.webshop.privateMeta.numberingType)
|
|
907
|
+
this.validAt = new Date(); // will get flattened AFTER calculations
|
|
908
|
+
this.validAt.setMilliseconds(0);
|
|
909
|
+
this.number = await WebshopCounter.getNextNumber(this.webshopId, this.webshop.privateMeta.numberingType);
|
|
906
910
|
|
|
907
911
|
if (payment && !Order.payment.isLoaded(this)) {
|
|
908
|
-
this.setRelation(Order.payment, payment)
|
|
912
|
+
this.setRelation(Order.payment, payment);
|
|
909
913
|
}
|
|
910
914
|
|
|
911
915
|
// Now we have a number, update the payment
|
|
912
916
|
if (payment && payment.method === PaymentMethod.Transfer) {
|
|
913
917
|
// Only now we can update the transfer description, since we need the order number as a reference
|
|
914
|
-
payment.transferSettings = webshop.meta.transferSettings.fillMissing(organization.mappedTransferSettings)
|
|
918
|
+
payment.transferSettings = webshop.meta.transferSettings.fillMissing(organization.mappedTransferSettings);
|
|
915
919
|
|
|
916
920
|
if (!payment.transferSettings.iban) {
|
|
917
921
|
throw new SimpleError({
|
|
918
|
-
code:
|
|
919
|
-
message:
|
|
920
|
-
human:
|
|
921
|
-
})
|
|
922
|
+
code: 'missing_iban',
|
|
923
|
+
message: 'Missing IBAN',
|
|
924
|
+
human: 'Er is geen rekeningnummer ingesteld voor overschrijvingen. Contacteer de beheerder.',
|
|
925
|
+
});
|
|
922
926
|
}
|
|
923
|
-
payment.generateDescription(organization, this.number.toString(), this.getTransferReplacements())
|
|
927
|
+
payment.generateDescription(organization, this.number.toString(), this.getTransferReplacements());
|
|
924
928
|
await payment.save();
|
|
925
929
|
}
|
|
926
930
|
|
|
927
|
-
await this.save()
|
|
931
|
+
await this.save();
|
|
928
932
|
|
|
929
933
|
if (this.data.customer.email.length > 0) {
|
|
930
|
-
const webshop = this.webshop
|
|
931
|
-
const organization = webshop.organization
|
|
932
|
-
|
|
933
|
-
const { from, replyTo } = organization.getEmail(webshop.privateMeta.defaultEmailId, true)
|
|
934
|
-
|
|
934
|
+
const webshop = this.webshop;
|
|
935
|
+
const organization = webshop.organization;
|
|
936
|
+
|
|
937
|
+
const { from, replyTo } = organization.getEmail(webshop.privateMeta.defaultEmailId, true);
|
|
938
|
+
|
|
935
939
|
if (tickets.length > 0) {
|
|
936
940
|
// Also send a copy
|
|
937
941
|
if (payment && payment.method === PaymentMethod.PointOfSale) {
|
|
938
942
|
await this.sendEmailTemplate({
|
|
939
943
|
type: EmailTemplateType.TicketsConfirmationPOS,
|
|
940
944
|
from,
|
|
941
|
-
replyTo
|
|
942
|
-
})
|
|
943
|
-
}
|
|
945
|
+
replyTo,
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
else {
|
|
944
949
|
await this.sendEmailTemplate({
|
|
945
950
|
type: EmailTemplateType.TicketsConfirmation,
|
|
946
951
|
from,
|
|
947
|
-
replyTo
|
|
948
|
-
})
|
|
952
|
+
replyTo,
|
|
953
|
+
});
|
|
949
954
|
}
|
|
950
|
-
}
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
951
957
|
if (this.webshop.meta.ticketType === WebshopTicketType.None) {
|
|
952
|
-
|
|
953
958
|
if (payment && payment.method === PaymentMethod.Transfer) {
|
|
954
959
|
// Also send a copy
|
|
955
960
|
await this.sendEmailTemplate({
|
|
956
961
|
type: EmailTemplateType.OrderConfirmationTransfer,
|
|
957
962
|
from,
|
|
958
|
-
replyTo
|
|
959
|
-
})
|
|
960
|
-
}
|
|
963
|
+
replyTo,
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
else if (payment && payment.method === PaymentMethod.PointOfSale) {
|
|
961
967
|
await this.sendEmailTemplate({
|
|
962
968
|
type: EmailTemplateType.OrderConfirmationPOS,
|
|
963
969
|
from,
|
|
964
|
-
replyTo
|
|
965
|
-
})
|
|
966
|
-
}
|
|
970
|
+
replyTo,
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
967
974
|
// Also send a copy
|
|
968
975
|
await this.sendEmailTemplate({
|
|
969
976
|
type: EmailTemplateType.OrderConfirmationOnline,
|
|
970
977
|
from,
|
|
971
|
-
replyTo
|
|
972
|
-
})
|
|
978
|
+
replyTo,
|
|
979
|
+
});
|
|
973
980
|
}
|
|
974
|
-
|
|
975
|
-
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
976
983
|
await this.sendEmailTemplate({
|
|
977
984
|
type: EmailTemplateType.TicketsConfirmationTransfer,
|
|
978
985
|
from,
|
|
979
|
-
replyTo
|
|
980
|
-
})
|
|
986
|
+
replyTo,
|
|
987
|
+
});
|
|
981
988
|
}
|
|
982
989
|
}
|
|
983
990
|
}
|
|
984
991
|
|
|
985
992
|
if (this.webshop.privateMeta.notificationEmails) {
|
|
986
|
-
const webshop = this.webshop
|
|
987
|
-
const organization = webshop.organization
|
|
988
|
-
const { from, replyTo } = organization.getEmail(webshop.privateMeta.defaultEmailId, true)
|
|
993
|
+
const webshop = this.webshop;
|
|
994
|
+
const organization = webshop.organization;
|
|
995
|
+
const { from, replyTo } = organization.getEmail(webshop.privateMeta.defaultEmailId, true);
|
|
989
996
|
const i18n = organization.i18n;
|
|
990
997
|
|
|
991
|
-
const webshopDashboardUrl =
|
|
998
|
+
const webshopDashboardUrl = 'https://' + (STAMHOOFD.domains.dashboard ?? 'stamhoofd.app') + '/' + i18n.locale + '/webshops/' + Formatter.slug(webshop.meta.name) + '/orders';
|
|
992
999
|
|
|
993
1000
|
// Send an email to all these notification emails
|
|
994
1001
|
for (const email of this.webshop.privateMeta.notificationEmails) {
|
|
@@ -1001,11 +1008,11 @@ export class Order extends Model {
|
|
|
1001
1008
|
replacements: [
|
|
1002
1009
|
Replacement.create({
|
|
1003
1010
|
token: 'orderUrl',
|
|
1004
|
-
value: webshopDashboardUrl
|
|
1005
|
-
})
|
|
1006
|
-
]
|
|
1007
|
-
})
|
|
1008
|
-
})
|
|
1011
|
+
value: webshopDashboardUrl,
|
|
1012
|
+
}),
|
|
1013
|
+
],
|
|
1014
|
+
}),
|
|
1015
|
+
});
|
|
1009
1016
|
}
|
|
1010
1017
|
}
|
|
1011
1018
|
}
|