@stamhoofd/structures 2.5.0 → 2.7.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.
Files changed (251) hide show
  1. package/dist/index.d.ts +1 -7
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -7
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/BalanceItemDetailed.d.ts +11 -3
  6. package/dist/src/BalanceItemDetailed.d.ts.map +1 -1
  7. package/dist/src/BalanceItemDetailed.js +15 -7
  8. package/dist/src/BalanceItemDetailed.js.map +1 -1
  9. package/dist/src/Event.d.ts +2 -1
  10. package/dist/src/Event.d.ts.map +1 -1
  11. package/dist/src/Event.js +7 -3
  12. package/dist/src/Event.js.map +1 -1
  13. package/dist/src/Group.d.ts +5 -0
  14. package/dist/src/Group.d.ts.map +1 -1
  15. package/dist/src/Group.js +8 -1
  16. package/dist/src/Group.js.map +1 -1
  17. package/dist/src/GroupSettings.d.ts +58 -19
  18. package/dist/src/GroupSettings.d.ts.map +1 -1
  19. package/dist/src/GroupSettings.js +188 -34
  20. package/dist/src/GroupSettings.js.map +1 -1
  21. package/dist/src/RegistrationPeriod.d.ts +1 -0
  22. package/dist/src/RegistrationPeriod.d.ts.map +1 -1
  23. package/dist/src/RegistrationPeriod.js +3 -0
  24. package/dist/src/RegistrationPeriod.js.map +1 -1
  25. package/dist/src/StockReservation.d.ts +20 -0
  26. package/dist/src/StockReservation.d.ts.map +1 -0
  27. package/dist/src/StockReservation.js +91 -0
  28. package/dist/src/StockReservation.js.map +1 -0
  29. package/dist/src/Version.d.ts +1 -1
  30. package/dist/src/Version.js +1 -1
  31. package/dist/src/addresses/Address.d.ts +4 -0
  32. package/dist/src/addresses/Address.d.ts.map +1 -1
  33. package/dist/src/addresses/Address.js +6 -0
  34. package/dist/src/addresses/Address.js.map +1 -1
  35. package/dist/src/email/EditorSmartVariable.d.ts.map +1 -1
  36. package/dist/src/email/EditorSmartVariable.js +7 -11
  37. package/dist/src/email/EditorSmartVariable.js.map +1 -1
  38. package/dist/src/email/Email.d.ts +4 -3
  39. package/dist/src/email/Email.d.ts.map +1 -1
  40. package/dist/src/email/Email.js +5 -4
  41. package/dist/src/email/Email.js.map +1 -1
  42. package/dist/src/members/Member.d.ts +7 -0
  43. package/dist/src/members/Member.d.ts.map +1 -1
  44. package/dist/src/members/Member.js +34 -1
  45. package/dist/src/members/Member.js.map +1 -1
  46. package/dist/src/members/MemberDetails.d.ts +8 -11
  47. package/dist/src/members/MemberDetails.d.ts.map +1 -1
  48. package/dist/src/members/MemberDetails.js +92 -51
  49. package/dist/src/members/MemberDetails.js.map +1 -1
  50. package/dist/src/members/MemberPlatformMembership.d.ts +1 -0
  51. package/dist/src/members/MemberPlatformMembership.d.ts.map +1 -1
  52. package/dist/src/members/MemberPlatformMembership.js +3 -0
  53. package/dist/src/members/MemberPlatformMembership.js.map +1 -1
  54. package/dist/src/members/MemberWithRegistrationsBlob.d.ts +1 -1
  55. package/dist/src/members/MemberWithRegistrationsBlob.d.ts.map +1 -1
  56. package/dist/src/members/MemberWithRegistrationsBlob.js +35 -12
  57. package/dist/src/members/MemberWithRegistrationsBlob.js.map +1 -1
  58. package/dist/src/members/PaymentDetailed.d.ts +3 -0
  59. package/dist/src/members/PaymentDetailed.d.ts.map +1 -1
  60. package/dist/src/members/PaymentDetailed.js +7 -8
  61. package/dist/src/members/PaymentDetailed.js.map +1 -1
  62. package/dist/src/members/PaymentGeneral.d.ts +5 -2
  63. package/dist/src/members/PaymentGeneral.d.ts.map +1 -1
  64. package/dist/src/members/PaymentGeneral.js +3 -5
  65. package/dist/src/members/PaymentGeneral.js.map +1 -1
  66. package/dist/src/members/PlatformMember.d.ts +6 -2
  67. package/dist/src/members/PlatformMember.d.ts.map +1 -1
  68. package/dist/src/members/PlatformMember.js +68 -18
  69. package/dist/src/members/PlatformMember.js.map +1 -1
  70. package/dist/src/members/Registration.d.ts +12 -0
  71. package/dist/src/members/Registration.d.ts.map +1 -1
  72. package/dist/src/members/Registration.js +18 -3
  73. package/dist/src/members/Registration.js.map +1 -1
  74. package/dist/src/members/RegistrationWithMember.d.ts +3 -2
  75. package/dist/src/members/RegistrationWithMember.d.ts.map +1 -1
  76. package/dist/src/members/RegistrationWithMember.js +7 -1
  77. package/dist/src/members/RegistrationWithMember.js.map +1 -1
  78. package/dist/src/members/checkout/BalanceItemCartItem.d.ts +3 -1
  79. package/dist/src/members/checkout/BalanceItemCartItem.d.ts.map +1 -1
  80. package/dist/src/members/checkout/BalanceItemCartItem.js +11 -9
  81. package/dist/src/members/checkout/BalanceItemCartItem.js.map +1 -1
  82. package/dist/src/members/checkout/RegisterCart.d.ts +16 -2
  83. package/dist/src/members/checkout/RegisterCart.d.ts.map +1 -1
  84. package/dist/src/members/checkout/RegisterCart.js +95 -17
  85. package/dist/src/members/checkout/RegisterCart.js.map +1 -1
  86. package/dist/src/members/checkout/RegisterCheckout.d.ts +19 -0
  87. package/dist/src/members/checkout/RegisterCheckout.d.ts.map +1 -1
  88. package/dist/src/members/checkout/RegisterCheckout.js +38 -1
  89. package/dist/src/members/checkout/RegisterCheckout.js.map +1 -1
  90. package/dist/src/members/checkout/RegisterItem.d.ts +37 -19
  91. package/dist/src/members/checkout/RegisterItem.d.ts.map +1 -1
  92. package/dist/src/members/checkout/RegisterItem.js +283 -118
  93. package/dist/src/members/checkout/RegisterItem.js.map +1 -1
  94. package/esm/dist/index.d.ts +1 -7
  95. package/esm/dist/index.d.ts.map +1 -1
  96. package/esm/dist/index.js +1 -7
  97. package/esm/dist/index.js.map +1 -1
  98. package/esm/dist/src/BalanceItemDetailed.d.ts +11 -3
  99. package/esm/dist/src/BalanceItemDetailed.d.ts.map +1 -1
  100. package/esm/dist/src/BalanceItemDetailed.js +15 -7
  101. package/esm/dist/src/BalanceItemDetailed.js.map +1 -1
  102. package/esm/dist/src/Event.d.ts +2 -1
  103. package/esm/dist/src/Event.d.ts.map +1 -1
  104. package/esm/dist/src/Event.js +7 -3
  105. package/esm/dist/src/Event.js.map +1 -1
  106. package/esm/dist/src/Group.d.ts +5 -0
  107. package/esm/dist/src/Group.d.ts.map +1 -1
  108. package/esm/dist/src/Group.js +9 -2
  109. package/esm/dist/src/Group.js.map +1 -1
  110. package/esm/dist/src/GroupSettings.d.ts +58 -19
  111. package/esm/dist/src/GroupSettings.d.ts.map +1 -1
  112. package/esm/dist/src/GroupSettings.js +188 -34
  113. package/esm/dist/src/GroupSettings.js.map +1 -1
  114. package/esm/dist/src/RegistrationPeriod.d.ts +1 -0
  115. package/esm/dist/src/RegistrationPeriod.d.ts.map +1 -1
  116. package/esm/dist/src/RegistrationPeriod.js +3 -0
  117. package/esm/dist/src/RegistrationPeriod.js.map +1 -1
  118. package/esm/dist/src/StockReservation.d.ts +20 -0
  119. package/esm/dist/src/StockReservation.d.ts.map +1 -0
  120. package/esm/dist/src/StockReservation.js +87 -0
  121. package/esm/dist/src/StockReservation.js.map +1 -0
  122. package/esm/dist/src/Version.d.ts +1 -1
  123. package/esm/dist/src/Version.js +1 -1
  124. package/esm/dist/src/addresses/Address.d.ts +4 -0
  125. package/esm/dist/src/addresses/Address.d.ts.map +1 -1
  126. package/esm/dist/src/addresses/Address.js +6 -0
  127. package/esm/dist/src/addresses/Address.js.map +1 -1
  128. package/esm/dist/src/email/EditorSmartVariable.d.ts.map +1 -1
  129. package/esm/dist/src/email/EditorSmartVariable.js +8 -12
  130. package/esm/dist/src/email/EditorSmartVariable.js.map +1 -1
  131. package/esm/dist/src/email/Email.d.ts +4 -3
  132. package/esm/dist/src/email/Email.d.ts.map +1 -1
  133. package/esm/dist/src/email/Email.js +5 -4
  134. package/esm/dist/src/email/Email.js.map +1 -1
  135. package/esm/dist/src/members/Member.d.ts +7 -0
  136. package/esm/dist/src/members/Member.d.ts.map +1 -1
  137. package/esm/dist/src/members/Member.js +32 -0
  138. package/esm/dist/src/members/Member.js.map +1 -1
  139. package/esm/dist/src/members/MemberDetails.d.ts +8 -11
  140. package/esm/dist/src/members/MemberDetails.d.ts.map +1 -1
  141. package/esm/dist/src/members/MemberDetails.js +92 -51
  142. package/esm/dist/src/members/MemberDetails.js.map +1 -1
  143. package/esm/dist/src/members/MemberPlatformMembership.d.ts +1 -0
  144. package/esm/dist/src/members/MemberPlatformMembership.d.ts.map +1 -1
  145. package/esm/dist/src/members/MemberPlatformMembership.js +3 -0
  146. package/esm/dist/src/members/MemberPlatformMembership.js.map +1 -1
  147. package/esm/dist/src/members/MemberWithRegistrationsBlob.d.ts +1 -1
  148. package/esm/dist/src/members/MemberWithRegistrationsBlob.d.ts.map +1 -1
  149. package/esm/dist/src/members/MemberWithRegistrationsBlob.js +35 -12
  150. package/esm/dist/src/members/MemberWithRegistrationsBlob.js.map +1 -1
  151. package/esm/dist/src/members/PaymentDetailed.d.ts +3 -0
  152. package/esm/dist/src/members/PaymentDetailed.d.ts.map +1 -1
  153. package/esm/dist/src/members/PaymentDetailed.js +7 -8
  154. package/esm/dist/src/members/PaymentDetailed.js.map +1 -1
  155. package/esm/dist/src/members/PaymentGeneral.d.ts +5 -2
  156. package/esm/dist/src/members/PaymentGeneral.d.ts.map +1 -1
  157. package/esm/dist/src/members/PaymentGeneral.js +3 -5
  158. package/esm/dist/src/members/PaymentGeneral.js.map +1 -1
  159. package/esm/dist/src/members/PlatformMember.d.ts +6 -2
  160. package/esm/dist/src/members/PlatformMember.d.ts.map +1 -1
  161. package/esm/dist/src/members/PlatformMember.js +68 -18
  162. package/esm/dist/src/members/PlatformMember.js.map +1 -1
  163. package/esm/dist/src/members/Registration.d.ts +12 -0
  164. package/esm/dist/src/members/Registration.d.ts.map +1 -1
  165. package/esm/dist/src/members/Registration.js +19 -4
  166. package/esm/dist/src/members/Registration.js.map +1 -1
  167. package/esm/dist/src/members/RegistrationWithMember.d.ts +3 -2
  168. package/esm/dist/src/members/RegistrationWithMember.d.ts.map +1 -1
  169. package/esm/dist/src/members/RegistrationWithMember.js +8 -2
  170. package/esm/dist/src/members/RegistrationWithMember.js.map +1 -1
  171. package/esm/dist/src/members/checkout/BalanceItemCartItem.d.ts +3 -1
  172. package/esm/dist/src/members/checkout/BalanceItemCartItem.d.ts.map +1 -1
  173. package/esm/dist/src/members/checkout/BalanceItemCartItem.js +11 -9
  174. package/esm/dist/src/members/checkout/BalanceItemCartItem.js.map +1 -1
  175. package/esm/dist/src/members/checkout/RegisterCart.d.ts +16 -2
  176. package/esm/dist/src/members/checkout/RegisterCart.d.ts.map +1 -1
  177. package/esm/dist/src/members/checkout/RegisterCart.js +96 -18
  178. package/esm/dist/src/members/checkout/RegisterCart.js.map +1 -1
  179. package/esm/dist/src/members/checkout/RegisterCheckout.d.ts +19 -0
  180. package/esm/dist/src/members/checkout/RegisterCheckout.d.ts.map +1 -1
  181. package/esm/dist/src/members/checkout/RegisterCheckout.js +38 -1
  182. package/esm/dist/src/members/checkout/RegisterCheckout.js.map +1 -1
  183. package/esm/dist/src/members/checkout/RegisterItem.d.ts +37 -19
  184. package/esm/dist/src/members/checkout/RegisterItem.d.ts.map +1 -1
  185. package/esm/dist/src/members/checkout/RegisterItem.js +283 -118
  186. package/esm/dist/src/members/checkout/RegisterItem.js.map +1 -1
  187. package/package.json +2 -2
  188. package/dist/src/members/MemberWithRegistrations.d.ts +0 -52
  189. package/dist/src/members/MemberWithRegistrations.d.ts.map +0 -1
  190. package/dist/src/members/MemberWithRegistrations.js +0 -156
  191. package/dist/src/members/MemberWithRegistrations.js.map +0 -1
  192. package/dist/src/members/checkout/OldRegisterCart.d.ts +0 -50
  193. package/dist/src/members/checkout/OldRegisterCart.d.ts.map +0 -1
  194. package/dist/src/members/checkout/OldRegisterCart.js +0 -207
  195. package/dist/src/members/checkout/OldRegisterCart.js.map +0 -1
  196. package/dist/src/members/checkout/OldRegisterCartPriceCalculator.d.ts +0 -36
  197. package/dist/src/members/checkout/OldRegisterCartPriceCalculator.d.ts.map +0 -1
  198. package/dist/src/members/checkout/OldRegisterCartPriceCalculator.js +0 -339
  199. package/dist/src/members/checkout/OldRegisterCartPriceCalculator.js.map +0 -1
  200. package/dist/src/members/checkout/OldRegisterCartValidator.d.ts +0 -35
  201. package/dist/src/members/checkout/OldRegisterCartValidator.d.ts.map +0 -1
  202. package/dist/src/members/checkout/OldRegisterCartValidator.js +0 -309
  203. package/dist/src/members/checkout/OldRegisterCartValidator.js.map +0 -1
  204. package/dist/src/members/checkout/OldRegisterCheckout.d.ts +0 -22
  205. package/dist/src/members/checkout/OldRegisterCheckout.d.ts.map +0 -1
  206. package/dist/src/members/checkout/OldRegisterCheckout.js +0 -46
  207. package/dist/src/members/checkout/OldRegisterCheckout.js.map +0 -1
  208. package/dist/src/members/checkout/OldRegisterItem.d.ts +0 -46
  209. package/dist/src/members/checkout/OldRegisterItem.d.ts.map +0 -1
  210. package/dist/src/members/checkout/OldRegisterItem.js +0 -89
  211. package/dist/src/members/checkout/OldRegisterItem.js.map +0 -1
  212. package/dist/src/members/checkout/RegisterCartPriceCalculator.test.d.ts +0 -2
  213. package/dist/src/members/checkout/RegisterCartPriceCalculator.test.d.ts.map +0 -1
  214. package/dist/src/members/checkout/RegisterCartPriceCalculator.test.js +0 -1076
  215. package/dist/src/members/checkout/RegisterCartPriceCalculator.test.js.map +0 -1
  216. package/dist/src/members/checkout/UnknownMemberWithRegistrations.d.ts +0 -23
  217. package/dist/src/members/checkout/UnknownMemberWithRegistrations.d.ts.map +0 -1
  218. package/dist/src/members/checkout/UnknownMemberWithRegistrations.js +0 -3
  219. package/dist/src/members/checkout/UnknownMemberWithRegistrations.js.map +0 -1
  220. package/esm/dist/src/members/MemberWithRegistrations.d.ts +0 -52
  221. package/esm/dist/src/members/MemberWithRegistrations.d.ts.map +0 -1
  222. package/esm/dist/src/members/MemberWithRegistrations.js +0 -152
  223. package/esm/dist/src/members/MemberWithRegistrations.js.map +0 -1
  224. package/esm/dist/src/members/checkout/OldRegisterCart.d.ts +0 -50
  225. package/esm/dist/src/members/checkout/OldRegisterCart.d.ts.map +0 -1
  226. package/esm/dist/src/members/checkout/OldRegisterCart.js +0 -202
  227. package/esm/dist/src/members/checkout/OldRegisterCart.js.map +0 -1
  228. package/esm/dist/src/members/checkout/OldRegisterCartPriceCalculator.d.ts +0 -36
  229. package/esm/dist/src/members/checkout/OldRegisterCartPriceCalculator.d.ts.map +0 -1
  230. package/esm/dist/src/members/checkout/OldRegisterCartPriceCalculator.js +0 -334
  231. package/esm/dist/src/members/checkout/OldRegisterCartPriceCalculator.js.map +0 -1
  232. package/esm/dist/src/members/checkout/OldRegisterCartValidator.d.ts +0 -35
  233. package/esm/dist/src/members/checkout/OldRegisterCartValidator.d.ts.map +0 -1
  234. package/esm/dist/src/members/checkout/OldRegisterCartValidator.js +0 -305
  235. package/esm/dist/src/members/checkout/OldRegisterCartValidator.js.map +0 -1
  236. package/esm/dist/src/members/checkout/OldRegisterCheckout.d.ts +0 -22
  237. package/esm/dist/src/members/checkout/OldRegisterCheckout.d.ts.map +0 -1
  238. package/esm/dist/src/members/checkout/OldRegisterCheckout.js +0 -41
  239. package/esm/dist/src/members/checkout/OldRegisterCheckout.js.map +0 -1
  240. package/esm/dist/src/members/checkout/OldRegisterItem.d.ts +0 -46
  241. package/esm/dist/src/members/checkout/OldRegisterItem.d.ts.map +0 -1
  242. package/esm/dist/src/members/checkout/OldRegisterItem.js +0 -84
  243. package/esm/dist/src/members/checkout/OldRegisterItem.js.map +0 -1
  244. package/esm/dist/src/members/checkout/RegisterCartPriceCalculator.test.d.ts +0 -2
  245. package/esm/dist/src/members/checkout/RegisterCartPriceCalculator.test.d.ts.map +0 -1
  246. package/esm/dist/src/members/checkout/RegisterCartPriceCalculator.test.js +0 -1074
  247. package/esm/dist/src/members/checkout/RegisterCartPriceCalculator.test.js.map +0 -1
  248. package/esm/dist/src/members/checkout/UnknownMemberWithRegistrations.d.ts +0 -23
  249. package/esm/dist/src/members/checkout/UnknownMemberWithRegistrations.d.ts.map +0 -1
  250. package/esm/dist/src/members/checkout/UnknownMemberWithRegistrations.js +0 -2
  251. package/esm/dist/src/members/checkout/UnknownMemberWithRegistrations.js.map +0 -1
@@ -1,9 +1,10 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { ArrayDecoder, AutoEncoder, field, IntegerDecoder, StringDecoder } from "@simonbackx/simple-encoding";
3
3
  import { isSimpleError, isSimpleErrors, SimpleError, SimpleErrors } from "@simonbackx/simple-errors";
4
- import { Formatter } from "@stamhoofd/utility";
5
- import { GroupOption, GroupOptionMenu, GroupPrice, WaitingListType } from "../../GroupSettings";
6
4
  import { v4 as uuidv4 } from "uuid";
5
+ import { GroupType } from "../../Group";
6
+ import { GroupOption, GroupOptionMenu, GroupPrice, WaitingListType } from "../../GroupSettings";
7
+ import { StockReservation } from "../../StockReservation";
7
8
  export class RegisterItemOption extends AutoEncoder {
8
9
  constructor() {
9
10
  super(...arguments);
@@ -62,9 +63,13 @@ export class RegisterItem {
62
63
  });
63
64
  }
64
65
  constructor(data) {
65
- var _a, _b, _c;
66
+ var _a, _b, _c, _d, _e;
66
67
  this.options = [];
67
68
  this.calculatedPrice = 0;
69
+ /**
70
+ * These registrations will be replaced as part of this new registration (moving or updating a registration is possible this way)
71
+ */
72
+ this.replaceRegistrations = [];
68
73
  /**
69
74
  * Show an error in the cart for recovery
70
75
  */
@@ -72,12 +77,10 @@ export class RegisterItem {
72
77
  this.id = (_a = data.id) !== null && _a !== void 0 ? _a : uuidv4();
73
78
  this.member = data.member;
74
79
  this.group = data.group;
75
- if (this.group.settings.prices.length === 0) {
76
- throw new Error("Group has no prices");
77
- }
78
- this.groupPrice = (_b = data.groupPrice) !== null && _b !== void 0 ? _b : this.group.settings.prices[0];
80
+ this.groupPrice = (_c = (_b = data.groupPrice) !== null && _b !== void 0 ? _b : this.group.settings.prices[0]) !== null && _c !== void 0 ? _c : GroupPrice.create({ name: 'Ongeldig tarief', id: '' });
79
81
  this.organization = data.organization;
80
- this.options = (_c = data.options) !== null && _c !== void 0 ? _c : [];
82
+ this.options = (_d = data.options) !== null && _d !== void 0 ? _d : [];
83
+ this.replaceRegistrations = (_e = data.replaceRegistrations) !== null && _e !== void 0 ? _e : [];
81
84
  // Select all defaults
82
85
  for (const optionMenu of this.group.settings.optionMenus) {
83
86
  if (!optionMenu.multipleChoice) {
@@ -92,14 +95,46 @@ export class RegisterItem {
92
95
  }
93
96
  }
94
97
  }
98
+ get isInCart() {
99
+ return this.member.family.checkout.cart.contains(this);
100
+ }
95
101
  get showItemView() {
96
- return this.shouldUseWaitingList() || this.group.settings.prices.length > 1 || this.group.settings.optionMenus.length > 0;
102
+ return this.shouldUseWaitingList() || this.replaceRegistrations.length || this.group.settings.prices.length > 1 || this.group.settings.optionMenus.length > 0 || (!this.isInCart && !this.isValid);
97
103
  }
98
104
  calculatePrice() {
99
105
  this.calculatedPrice = this.groupPrice.price.forMember(this.member);
100
106
  for (const option of this.options) {
101
107
  this.calculatedPrice += option.option.price.forMember(this.member) * option.amount;
102
108
  }
109
+ for (const registration of this.replaceRegistrations) {
110
+ this.calculatedPrice -= registration.price;
111
+ }
112
+ }
113
+ get priceBreakown() {
114
+ let all = [];
115
+ let replacePrice = 0;
116
+ for (const registration of this.replaceRegistrations) {
117
+ replacePrice += registration.price;
118
+ all.push({
119
+ name: 'Terugbetaling ' + registration.group.settings.name,
120
+ price: -registration.price
121
+ });
122
+ }
123
+ const subtotal = this.calculatedPrice + replacePrice;
124
+ all = all.filter(a => a.price !== 0);
125
+ if (all.length > 0) {
126
+ all.unshift({
127
+ name: 'Subtotaal',
128
+ price: subtotal
129
+ });
130
+ }
131
+ return [
132
+ ...all,
133
+ {
134
+ name: 'Totaal',
135
+ price: this.calculatedPrice
136
+ }
137
+ ];
103
138
  }
104
139
  clone() {
105
140
  return new RegisterItem({
@@ -108,7 +143,8 @@ export class RegisterItem {
108
143
  group: this.group,
109
144
  organization: this.organization,
110
145
  groupPrice: this.groupPrice.clone(),
111
- options: this.options.map(o => o.clone())
146
+ options: this.options.map(o => o.clone()),
147
+ replaceRegistrations: this.replaceRegistrations.map(r => r.clone())
112
148
  });
113
149
  }
114
150
  copyFrom(item) {
@@ -116,22 +152,22 @@ export class RegisterItem {
116
152
  this.options = item.options.map(o => o.clone());
117
153
  this.calculatedPrice = item.calculatedPrice;
118
154
  }
119
- getFilteredPrices(options) {
155
+ getFilteredPrices() {
120
156
  return this.group.settings.prices.filter(p => {
121
- if (p.hidden && !options.admin) {
157
+ if (p.hidden && !this.checkout.isAdminFromSameOrganization) {
122
158
  return false;
123
159
  }
124
160
  return true;
125
161
  });
126
162
  }
127
- getFilteredOptionMenus(options) {
163
+ getFilteredOptionMenus() {
128
164
  return this.group.settings.optionMenus.filter(p => {
129
- return this.getFilteredOptions(p, options).length > 0;
165
+ return this.getFilteredOptions(p).length > 0;
130
166
  });
131
167
  }
132
- getFilteredOptions(menu, options) {
168
+ getFilteredOptions(menu) {
133
169
  return menu.options.filter(p => {
134
- if (p.hidden && !options.admin) {
170
+ if (p.hidden && !this.checkout.isAdminFromSameOrganization) {
135
171
  return false;
136
172
  }
137
173
  return true;
@@ -172,6 +208,10 @@ export class RegisterItem {
172
208
  group,
173
209
  organization
174
210
  });
211
+ //if (item.shouldUseWaitingList() && group.waitingList) {
212
+ // group = group.waitingList
213
+ // item = RegisterItem.defaultFor(member, group, organization);
214
+ //}
175
215
  return item;
176
216
  }
177
217
  /**
@@ -180,16 +220,25 @@ export class RegisterItem {
180
220
  refresh(group) {
181
221
  this.group = group;
182
222
  const errors = new SimpleErrors();
183
- const groupPrice = this.group.settings.prices.find(p => p.id === this.groupPrice.id);
184
- if (!groupPrice) {
223
+ if (this.group.settings.prices.length === 0) {
185
224
  errors.addError(new SimpleError({
186
225
  code: "product_unavailable",
187
226
  message: "Product unavailable",
188
- human: "Eén of meerdere tarieven van " + this.group.settings.name + " zijn niet meer beschikbaar"
227
+ human: "Er is iets fout met de tariefinstellingen van " + this.group.settings.name + ", waardoor je nu niet kan inschrijven. Neem contact op met een beheerder en vraag de tariefinstellingen na te kijken."
189
228
  }));
190
229
  }
191
230
  else {
192
- this.groupPrice = groupPrice;
231
+ const groupPrice = this.group.settings.prices.find(p => p.id === this.groupPrice.id);
232
+ if (!groupPrice) {
233
+ errors.addError(new SimpleError({
234
+ code: "product_unavailable",
235
+ message: "Product unavailable",
236
+ human: "Eén of meerdere tarieven van " + this.group.settings.name + " zijn niet meer beschikbaar"
237
+ }));
238
+ }
239
+ else {
240
+ this.groupPrice = groupPrice;
241
+ }
193
242
  }
194
243
  // Check all options
195
244
  const remainingMenus = this.group.settings.optionMenus.slice();
@@ -233,17 +282,18 @@ export class RegisterItem {
233
282
  errors.throwIfNotEmpty();
234
283
  }
235
284
  isAlreadyRegistered() {
236
- return !!this.member.member.registrations.find(r => r.groupId === this.group.id && (this.waitingList || r.registeredAt !== null) && r.deactivatedAt === null && r.waitingList === this.waitingList && r.cycle === this.group.cycle);
285
+ return !!this.member.member.registrations.find(r => r.groupId === this.group.id && r.registeredAt !== null && r.deactivatedAt === null);
237
286
  }
238
287
  hasReachedCategoryMaximum() {
288
+ if (this.group.type !== GroupType.Membership) {
289
+ return false;
290
+ }
239
291
  const parents = this.group.getParentCategories(this.organization.period.settings.categories, false);
240
292
  for (const parent of parents) {
241
293
  if (parent.settings.maximumRegistrations !== null) {
242
- const count = this.member.member.registrations.filter(r => {
243
- if (r.registeredAt !== null && !r.waitingList && r.deactivatedAt === null && parent.groupIds.includes(r.groupId)) {
244
- // Check cycle (only count current periods, not previous periods)
245
- const g = this.organization.groups.find(gg => gg.id === r.groupId);
246
- return g && g.cycle === r.cycle;
294
+ const count = this.member.patchedMember.registrations.filter(r => {
295
+ if (r.registeredAt !== null && r.deactivatedAt === null && parent.groupIds.includes(r.groupId)) {
296
+ return true;
247
297
  }
248
298
  return false;
249
299
  }).length;
@@ -258,51 +308,73 @@ export class RegisterItem {
258
308
  return false;
259
309
  }
260
310
  isInvited() {
261
- return !!this.member.member.registrations.find(r => r.groupId === this.group.id && r.waitingList && r.canRegister && r.cycle === this.group.cycle);
311
+ return !!this.member.member.registrations.find(r => r.groupId === this.group.id && r.registeredAt === null && r.canRegister);
262
312
  }
263
313
  doesMeetRequireGroupIds() {
264
314
  if (this.group.settings.requireGroupIds.length > 0) {
265
315
  const hasGroup = this.member.member.registrations.find(r => {
266
- const registrationGroup = this.organization.groups.find(g => g.id === r.groupId);
267
- if (!registrationGroup) {
268
- return false;
269
- }
270
- return this.group.settings.requireGroupIds.includes(r.groupId) && r.registeredAt !== null && r.deactivatedAt === null && !r.waitingList && r.cycle === registrationGroup.cycle;
316
+ return r.registeredAt !== null && r.deactivatedAt === null && this.group.settings.requireGroupIds.includes(r.groupId);
271
317
  });
272
- if (!hasGroup && !this.checkout.cart.items.find(item => this.group.settings.requireGroupIds.includes(item.group.id) && item.member.member.id === this.member.member.id && !item.waitingList)) {
318
+ if (!hasGroup && !this.checkout.cart.items.find(item => item.member.id === this.member.id && this.group.settings.requireGroupIds.includes(item.group.id))) {
319
+ return false;
320
+ }
321
+ }
322
+ if (this.group.settings.requireDefaultAgeGroupIds.length > 0) {
323
+ const hasGroup = this.member.member.registrations.find(r => {
324
+ return r.registeredAt !== null && r.deactivatedAt === null && r.group.defaultAgeGroupId && this.group.settings.requireDefaultAgeGroupIds.includes(r.group.defaultAgeGroupId);
325
+ });
326
+ if (!hasGroup && !this.checkout.cart.items.find(item => item.member.id === this.member.id && item.group.defaultAgeGroupId && this.group.settings.requireDefaultAgeGroupIds.includes(item.group.defaultAgeGroupId))) {
273
327
  return false;
274
328
  }
275
329
  }
276
330
  return true;
277
331
  }
278
- isExistingMemberOrFamily() {
279
- return this.member.isExistingMember(this.group.organizationId) || (this.group.settings.priorityForFamily && !!this.family.members.find(f => f.isExistingMember(this.group.organizationId)));
332
+ doesMeetRequireOrganizationIds() {
333
+ if (this.group.settings.requireOrganizationIds.length > 0) {
334
+ const hasGroup = this.member.member.registrations.find(r => {
335
+ return r.group.type === GroupType.Membership && this.group.settings.requireOrganizationIds.includes(r.organizationId) && r.registeredAt !== null && r.deactivatedAt === null;
336
+ });
337
+ if (!hasGroup && !this.checkout.cart.items.find(item => item.member.id === this.member.id && this.group.settings.requireOrganizationIds.includes(item.organization.id))) {
338
+ return false;
339
+ }
340
+ }
341
+ return true;
280
342
  }
281
- get rowLabel() {
282
- if (this.isInvited()) {
283
- return 'Uitnodiging';
343
+ doesMeetRequireOrganizationTags() {
344
+ if (this.group.settings.requireOrganizationTags.length > 0) {
345
+ const hasOrganization = this.member.filterOrganizations({ currentPeriod: true, types: [GroupType.Membership] }).find(organization => {
346
+ return organization.meta.matchTags(this.group.settings.requireOrganizationTags);
347
+ });
348
+ if (!hasOrganization && !this.checkout.cart.items.find(item => item.member.id === this.member.id && item.organization.meta.matchTags(this.group.settings.requireOrganizationTags))) {
349
+ return false;
350
+ }
284
351
  }
285
- return null;
352
+ return true;
286
353
  }
287
- get infoDescription() {
288
- if (this.isInvited()) {
289
- return 'Je bent uitgenodigd om in te schrijven voor deze groep';
354
+ doesMeetRequirePlatformMembershipOn() {
355
+ if (this.group.settings.requirePlatformMembershipOn !== null) {
356
+ const requirePlatformMembershipOn = this.group.settings.requirePlatformMembershipOn;
357
+ return !!this.member.patchedMember.platformMemberships.find(m => m.isActive(requirePlatformMembershipOn));
290
358
  }
291
- if (this.waitingList) {
292
- if (this.group.settings.waitingListType === WaitingListType.All) {
293
- return 'Je kan enkel inschrijven voor de wachtlijst';
294
- }
295
- const existingMember = this.isExistingMemberOrFamily();
296
- if (this.group.settings.waitingListType === WaitingListType.ExistingMembersFirst && !existingMember) {
297
- return 'Nieuwe leden kunnen enkel inschrijven voor de wachtlijst';
298
- }
299
- if (this.group.waitingList) {
300
- if (this.hasReachedGroupMaximum()) {
301
- return 'De inschrijvingen zijn volzet, je kan enkel inschrijven voor de wachtlijst';
302
- }
359
+ return true;
360
+ }
361
+ isExistingMemberOrFamily() {
362
+ return this.member.isExistingMember(this.group.organizationId) || (this.group.settings.priorityForFamily && !!this.family.members.find(f => f.isExistingMember(this.group.organizationId)));
363
+ }
364
+ get description() {
365
+ const descriptions = [];
366
+ if (this.replaceRegistrations.length > 0) {
367
+ for (const registration of this.replaceRegistrations) {
368
+ descriptions.push("Verplaatsen vanaf " + registration.group.settings.name);
303
369
  }
304
370
  }
305
- return null;
371
+ if (this.getFilteredPrices().length > 1) {
372
+ descriptions.push(this.groupPrice.name);
373
+ }
374
+ for (const option of this.options) {
375
+ descriptions.push(option.optionMenu.name + ': ' + option.option.name + (option.option.allowAmount ? ` x ${option.amount}` : ""));
376
+ }
377
+ return descriptions.filter(d => !!d).join("\n");
306
378
  }
307
379
  shouldUseWaitingList() {
308
380
  if (this.group.settings.waitingListType === WaitingListType.All) {
@@ -346,19 +418,60 @@ export class RegisterItem {
346
418
  }
347
419
  return null;
348
420
  }
349
- validate() {
421
+ get validationWarning() {
422
+ if (this.validationError) {
423
+ return null;
424
+ }
425
+ if (!this.member.family.checkout.isAdminFromSameOrganization) {
426
+ // Warnings are only for admins
427
+ return null;
428
+ }
429
+ try {
430
+ this.validate({ warnings: true });
431
+ }
432
+ catch (e) {
433
+ if (isSimpleError(e) || isSimpleErrors(e)) {
434
+ return e.getHuman();
435
+ }
436
+ throw e;
437
+ }
438
+ return null;
439
+ }
440
+ get isValid() {
441
+ return this.validationError === null;
442
+ }
443
+ validate(options) {
350
444
  var _a;
351
445
  this.cartError = null;
352
446
  this.refresh(this.group);
447
+ const checkout = this.member.family.checkout;
448
+ const admin = checkout.isAdminFromSameOrganization && !(options === null || options === void 0 ? void 0 : options.warnings);
353
449
  if (this.group.organizationId !== this.organization.id) {
354
450
  throw new Error("Group and organization do not match in RegisterItem.validate");
355
451
  }
356
- if (!this.checkout.cart.contains(this)) {
357
- if (!this.checkout.cart.canAdd(this)) {
452
+ if (checkout.asOrganizationId && !admin && !this.group.settings.allowRegistrationsByOrganization) {
453
+ throw new SimpleError({
454
+ code: "as_organization_disabled",
455
+ message: "allowRegistrationsByOrganization disabled",
456
+ human: "Inschrijvingen door organisaties zijn niet toegestaan voor " + this.group.settings.name,
457
+ });
458
+ }
459
+ for (const registration of this.replaceRegistrations) {
460
+ // todo: check if you are allowed to move
461
+ if (registration.member.id !== this.member.id) {
358
462
  throw new SimpleError({
359
- code: "already_registered",
360
- message: "Already registered",
361
- human: `Reken jouw winkelmandje eerst af. Het is niet mogelijk om deze inschrijving samen af te rekenen omdat het inschrijvingsgeld aan een andere partij betaald moet worden.`
463
+ code: "invalid_move",
464
+ message: "Invalid member in replaceRegistration",
465
+ human: "Je wilt een inschrijving verplaatsen van een ander lid in ruil voor een ander lid. Dit is niet toegestaan.",
466
+ field: "replaceRegistrations"
467
+ });
468
+ }
469
+ if (registration.group.organizationId !== this.organization.id) {
470
+ throw new SimpleError({
471
+ code: "invalid_move",
472
+ message: "Invalid organization in replaceRegistration",
473
+ human: "Je wilt een inschrijving verplaatsen van een andere organisatie. Dit is niet toegestaan.",
474
+ field: "replaceRegistrations"
362
475
  });
363
476
  }
364
477
  }
@@ -375,83 +488,95 @@ export class RegisterItem {
375
488
  throw new SimpleError({
376
489
  code: "maximum_reached",
377
490
  message: "Maximum reached",
378
- human: `Je kan niet meer inschrijven voor ${this.group.settings.name} omdat je al ingeschreven bent of aan het inschrijven bent voor een groep die je niet kan combineren.`
491
+ human: `Je kan niet meer inschrijven voor ${this.group.settings.name} omdat ${this.member.patchedMember.name} al ingeschreven is voor een groep die je niet kan combineren.`
379
492
  });
380
493
  }
381
494
  // Check if we have an invite (doesn't matter if registrations are closed)
382
495
  if (this.isInvited()) {
383
496
  return;
384
497
  }
385
- if (this.group.notYetOpen) {
386
- throw new SimpleError({
387
- code: "not_yet_open",
388
- message: "Not yet open",
389
- human: `De inschrijvingen voor ${this.group.settings.name} zijn nog niet geopend.`
390
- });
391
- }
392
- if (this.group.closed) {
393
- throw new SimpleError({
394
- code: "closed",
395
- message: "Closed",
396
- human: `De inschrijvingen voor ${this.group.settings.name} zijn gesloten.`
397
- });
398
- }
399
- // Check if it fits
400
- if (this.member.member.details) {
401
- if (!this.member.member.details.doesMatchGroup(this.group)) {
402
- const error = this.member.member.details.getMatchingError(this.group);
498
+ if (!admin) {
499
+ if (this.group.notYetOpen) {
403
500
  throw new SimpleError({
404
- code: "not_matching",
405
- message: "Not matching",
406
- human: (_a = error === null || error === void 0 ? void 0 : error.description) !== null && _a !== void 0 ? _a : "Je voldoet niet aan de voorwaarden om in te schrijven voor deze groep."
501
+ code: "not_yet_open",
502
+ message: "Not yet open",
503
+ human: `De inschrijvingen voor ${this.group.settings.name} zijn nog niet geopend.`
407
504
  });
408
505
  }
409
- }
410
- // Check if registrations are limited
411
- if (!this.doesMeetRequireGroupIds()) {
412
- throw new SimpleError({
413
- code: "not_matching",
414
- message: "Not matching",
415
- human: "Inschrijving bij " + Formatter.joinLast(this.group.settings.requireGroupIds.map(id => { var _a, _b; return (_b = (_a = this.organization.groups.find(g => g.id === id)) === null || _a === void 0 ? void 0 : _a.settings.name) !== null && _b !== void 0 ? _b : "Onbekend"; }), ", ", " of ") + " is verplicht voor je kan inschrijven voor " + this.group.settings.name,
416
- });
417
- }
418
- const existingMember = this.isExistingMemberOrFamily();
419
- // Pre registrations?
420
- if (this.group.activePreRegistrationDate) {
421
- if (!existingMember) {
506
+ if (this.group.closed) {
422
507
  throw new SimpleError({
423
- code: "pre_registrations",
424
- message: "Pre registrations",
425
- human: "Momenteel zijn de voorinschrijvingen nog bezig voor " + this.group.settings.name + ". Dit is enkel voor bestaande leden" + (this.group.settings.priorityForFamily ? " en hun broers/zussen" : "") + "."
508
+ code: "closed",
509
+ message: "Closed",
510
+ human: `De inschrijvingen voor ${this.group.settings.name} zijn gesloten.`
426
511
  });
427
512
  }
428
- }
429
- if (!this.waitingList && this.shouldUseWaitingList()) {
430
- throw new SimpleError({
431
- code: "waiting_list_required",
432
- message: "Waiting list required",
433
- human: `${this.member.member.firstName} kan momenteel enkel voor de wachtlijst van ${this.group.settings.name} inschrijven.`
434
- });
435
- }
436
- if (!this.waitingList) {
437
- if (!this.group.waitingList) {
438
- if (this.hasReachedGroupMaximum()) {
513
+ // Check if it fits
514
+ if (this.member.member.details) {
515
+ if (!this.member.member.details.doesMatchGroup(this.group)) {
516
+ const error = this.member.member.details.getMatchingError(this.group);
439
517
  throw new SimpleError({
440
- code: "maximum_reached",
441
- message: "Maximum reached",
442
- human: `De inschrijvingen voor ${this.group.settings.name} zijn volzet. Je kan wel nog inschrijven voor de wachtlijst.`
518
+ code: "not_matching",
519
+ message: "Not matching: memberDetails",
520
+ human: (_a = error === null || error === void 0 ? void 0 : error.description) !== null && _a !== void 0 ? _a : `${this.member.patchedMember.name} voldoet niet aan de voorwaarden om in te schrijven voor deze groep.`
443
521
  });
444
522
  }
445
523
  }
446
- else {
447
- if (this.hasReachedGroupMaximum()) {
524
+ // Check if registrations are limited
525
+ if (!this.doesMeetRequireGroupIds()) {
526
+ throw new SimpleError({
527
+ code: "not_matching",
528
+ message: "Not matching: requireGroupIds",
529
+ human: `${this.member.patchedMember.name} voldoet niet aan de voorwaarden om in te schrijven voor deze groep (verplichte inschrijving bij leeftijdsgroep).`
530
+ });
531
+ }
532
+ if (!this.doesMeetRequireOrganizationIds()) {
533
+ throw new SimpleError({
534
+ code: "not_matching",
535
+ message: "Not matching: requireOrganizationIds",
536
+ human: `${this.member.patchedMember.name} kan pas inschrijven met een geldige actieve inschrijving (verplichte inschrijving bij lokale groep).`
537
+ });
538
+ }
539
+ if (!this.doesMeetRequireOrganizationTags()) {
540
+ throw new SimpleError({
541
+ code: "not_matching",
542
+ message: "Not matching: requireOrganizationIds",
543
+ human: `${this.member.patchedMember.name} kan pas inschrijven met een geldige actieve inschrijving (verplichte inschrijving in regio).`
544
+ });
545
+ }
546
+ if (!this.doesMeetRequirePlatformMembershipOn()) {
547
+ throw new SimpleError({
548
+ code: "not_matching",
549
+ message: "Not matching: requirePlatformMembershipOn",
550
+ human: `${this.member.patchedMember.name} kan pas inschrijven met een geldige aansluiting (en dus verzekering) bij de koepel`
551
+ });
552
+ }
553
+ const existingMember = this.isExistingMemberOrFamily();
554
+ // Pre registrations?
555
+ if (this.group.activePreRegistrationDate) {
556
+ if (!existingMember) {
448
557
  throw new SimpleError({
449
- code: "maximum_reached",
450
- message: "Maximum reached",
451
- human: `De inschrijvingen voor ${this.group.settings.name} zijn volzet.`
558
+ code: "pre_registrations",
559
+ message: "Pre registrations",
560
+ human: "Momenteel zijn de voorinschrijvingen nog bezig voor " + this.group.settings.name + ". Dit is enkel voor bestaande leden" + (this.group.settings.priorityForFamily ? " en hun broers/zussen" : "") + "."
452
561
  });
453
562
  }
454
563
  }
564
+ if (this.shouldUseWaitingList()) {
565
+ throw new SimpleError({
566
+ code: "waiting_list_required",
567
+ message: "Waiting list required",
568
+ human: `${this.member.member.firstName} kan momenteel enkel voor de wachtlijst van ${this.group.settings.name} inschrijven.`,
569
+ meta: { recoverable: true }
570
+ });
571
+ }
572
+ if (this.hasReachedGroupMaximum()) {
573
+ throw new SimpleError({
574
+ code: "maximum_reached",
575
+ message: "Maximum reached",
576
+ human: this.group.waitingList ? `De inschrijvingen voor ${this.group.settings.name} zijn volzet. Je kan wel nog inschrijven voor de wachtlijst.` : `De inschrijvingen voor ${this.group.settings.name} zijn volzet. `,
577
+ meta: { recoverable: true }
578
+ });
579
+ }
455
580
  }
456
581
  }
457
582
  static fromId(idRegisterItem, context) {
@@ -482,5 +607,45 @@ export class RegisterItem {
482
607
  }
483
608
  return this.organization.meta.registrationPaymentConfiguration;
484
609
  }
610
+ /**
611
+ * Returns the stock that will be taken (or freed if negative) by all the register items before this item
612
+ * and with the removed registrations freed up, so this can be negative
613
+ */
614
+ getCartPendingStockReservations() {
615
+ const deleteRegistrations = this.checkout.cart.deleteRegistrations.filter(r => r.groupId === this.group.id);
616
+ const cartIndex = this.checkout.cart.items.findIndex(i => i.id === this.id);
617
+ const itemsBefore = this.checkout.cart.items.slice(0, cartIndex === -1 ? undefined : cartIndex);
618
+ return StockReservation.removed(itemsBefore.flatMap(i => i.getPendingStockReservations()), // these will be removed
619
+ deleteRegistrations.flatMap(r => r.stockReservations) // these will be freed up
620
+ );
621
+ }
622
+ /**
623
+ * Stock that will be taken by this item
624
+ */
625
+ getPendingStockReservations() {
626
+ return [
627
+ // Global level stock reservations (stored in each group)
628
+ StockReservation.create({
629
+ objectId: this.group.id,
630
+ objectType: 'Group',
631
+ amount: 1,
632
+ children: [
633
+ // Group level stock reservatiosn (stored in the group)
634
+ StockReservation.create({
635
+ objectId: this.groupPrice.id,
636
+ objectType: 'GroupPrice',
637
+ amount: 1
638
+ }),
639
+ ...this.options.map(o => {
640
+ return StockReservation.create({
641
+ objectId: o.option.id,
642
+ objectType: 'GroupOption',
643
+ amount: o.amount
644
+ });
645
+ })
646
+ ]
647
+ })
648
+ ];
649
+ }
485
650
  }
486
651
  //# sourceMappingURL=RegisterItem.js.map