@sellout/models 0.0.150 → 0.0.152

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 (139) hide show
  1. package/.dist/graphql/fragments/season.fragment.d.ts +23 -0
  2. package/.dist/graphql/fragments/season.fragment.js +315 -0
  3. package/.dist/graphql/fragments/season.fragment.js.map +1 -0
  4. package/.dist/graphql/mutations/createEvent.mutation.js +1 -0
  5. package/.dist/graphql/mutations/createEvent.mutation.js.map +1 -1
  6. package/.dist/graphql/mutations/createFee.mutation.js +1 -0
  7. package/.dist/graphql/mutations/createFee.mutation.js.map +1 -1
  8. package/.dist/graphql/mutations/createSeason.mutation.d.ts +2 -0
  9. package/.dist/graphql/mutations/createSeason.mutation.js +72 -0
  10. package/.dist/graphql/mutations/createSeason.mutation.js.map +1 -0
  11. package/.dist/graphql/mutations/createSeasonOrder.mutation.d.ts +2 -0
  12. package/.dist/graphql/mutations/createSeasonOrder.mutation.js +65 -0
  13. package/.dist/graphql/mutations/createSeasonOrder.mutation.js.map +1 -0
  14. package/.dist/graphql/mutations/createSeasonOrderPaymentIntent.mutation.d.ts +2 -0
  15. package/.dist/graphql/mutations/createSeasonOrderPaymentIntent.mutation.js +18 -0
  16. package/.dist/graphql/mutations/createSeasonOrderPaymentIntent.mutation.js.map +1 -0
  17. package/.dist/graphql/mutations/publishEvent.mutation.js +6 -5
  18. package/.dist/graphql/mutations/publishEvent.mutation.js.map +1 -1
  19. package/.dist/graphql/mutations/publishSeason.mutation.d.ts +2 -0
  20. package/.dist/graphql/mutations/publishSeason.mutation.js +72 -0
  21. package/.dist/graphql/mutations/publishSeason.mutation.js.map +1 -0
  22. package/.dist/graphql/mutations/updateEvent.mutation.js +2 -1
  23. package/.dist/graphql/mutations/updateEvent.mutation.js.map +1 -1
  24. package/.dist/graphql/mutations/updateOrganization.mutation.js +1 -0
  25. package/.dist/graphql/mutations/updateOrganization.mutation.js.map +1 -1
  26. package/.dist/graphql/mutations/updateSeason.mutation.d.ts +2 -0
  27. package/.dist/graphql/mutations/updateSeason.mutation.js +71 -0
  28. package/.dist/graphql/mutations/updateSeason.mutation.js.map +1 -0
  29. package/.dist/graphql/queries/event.query.js +2 -0
  30. package/.dist/graphql/queries/event.query.js.map +1 -1
  31. package/.dist/graphql/queries/events.query.js +1 -0
  32. package/.dist/graphql/queries/events.query.js.map +1 -1
  33. package/.dist/graphql/queries/organizations.query.js +1 -0
  34. package/.dist/graphql/queries/organizations.query.js.map +1 -1
  35. package/.dist/graphql/queries/profile.query.js +3 -0
  36. package/.dist/graphql/queries/profile.query.js.map +1 -1
  37. package/.dist/graphql/queries/profiles.query.js +1 -0
  38. package/.dist/graphql/queries/profiles.query.js.map +1 -1
  39. package/.dist/graphql/queries/publicEvent.query.js +1 -0
  40. package/.dist/graphql/queries/publicEvent.query.js.map +1 -1
  41. package/.dist/graphql/queries/season.query.d.ts +2 -0
  42. package/.dist/graphql/queries/season.query.js +76 -0
  43. package/.dist/graphql/queries/season.query.js.map +1 -0
  44. package/.dist/graphql/queries/seasons.query.d.ts +2 -0
  45. package/.dist/graphql/queries/seasons.query.js +72 -0
  46. package/.dist/graphql/queries/seasons.query.js.map +1 -0
  47. package/.dist/interfaces/IAnalytics.d.ts +1 -0
  48. package/.dist/interfaces/IAnalytics.js.map +1 -1
  49. package/.dist/interfaces/ICreateOrderParams.d.ts +4 -1
  50. package/.dist/interfaces/IEvent.d.ts +1 -0
  51. package/.dist/interfaces/IFee.d.ts +1 -0
  52. package/.dist/interfaces/IOrder.d.ts +3 -1
  53. package/.dist/interfaces/IOrder.js.map +1 -1
  54. package/.dist/interfaces/IOrderQuery.d.ts +2 -0
  55. package/.dist/interfaces/IOrganization.d.ts +1 -0
  56. package/.dist/interfaces/ISeason.d.ts +76 -0
  57. package/.dist/interfaces/ISeason.js +34 -0
  58. package/.dist/interfaces/ISeason.js.map +1 -0
  59. package/.dist/interfaces/ISeasonCustomField.d.ts +13 -0
  60. package/.dist/interfaces/ISeasonCustomField.js +3 -0
  61. package/.dist/interfaces/ISeasonCustomField.js.map +1 -0
  62. package/.dist/interfaces/ISeasonQuery.d.ts +23 -0
  63. package/.dist/interfaces/ISeasonQuery.js +15 -0
  64. package/.dist/interfaces/ISeasonQuery.js.map +1 -0
  65. package/.dist/interfaces/ISeasonUpgrade.d.ts +16 -0
  66. package/.dist/interfaces/ISeasonUpgrade.js +3 -0
  67. package/.dist/interfaces/ISeasonUpgrade.js.map +1 -0
  68. package/.dist/schemas/Event.d.ts +4 -0
  69. package/.dist/schemas/Event.js +4 -0
  70. package/.dist/schemas/Event.js.map +1 -1
  71. package/.dist/schemas/Fee.d.ts +5 -0
  72. package/.dist/schemas/Fee.js +4 -0
  73. package/.dist/schemas/Fee.js.map +1 -1
  74. package/.dist/schemas/Order.d.ts +8 -0
  75. package/.dist/schemas/Order.js +8 -1
  76. package/.dist/schemas/Order.js.map +1 -1
  77. package/.dist/schemas/Organization.d.ts +5 -0
  78. package/.dist/schemas/Organization.js +5 -0
  79. package/.dist/schemas/Organization.js.map +1 -1
  80. package/.dist/schemas/Season.d.ts +679 -0
  81. package/.dist/schemas/Season.js +502 -0
  82. package/.dist/schemas/Season.js.map +1 -0
  83. package/.dist/sellout-proto.js +36603 -26718
  84. package/.dist/utils/EventUtil.js +32 -15
  85. package/.dist/utils/EventUtil.js.map +1 -1
  86. package/.dist/utils/FeeUtil.d.ts +1 -1
  87. package/.dist/utils/FeeUtil.js +19 -11
  88. package/.dist/utils/FeeUtil.js.map +1 -1
  89. package/.dist/utils/SeasonUtil.d.ts +66 -0
  90. package/.dist/utils/SeasonUtil.js +340 -0
  91. package/.dist/utils/SeasonUtil.js.map +1 -0
  92. package/package.json +3 -3
  93. package/src/graphql/fragments/season.fragment.ts +336 -0
  94. package/src/graphql/mutations/createEvent.mutation.ts +1 -0
  95. package/src/graphql/mutations/createFee.mutation.ts +2 -1
  96. package/src/graphql/mutations/createSeason.mutation.ts +68 -0
  97. package/src/graphql/mutations/createSeasonOrder.mutation.ts +61 -0
  98. package/src/graphql/mutations/createSeasonOrderPaymentIntent.mutation.ts +14 -0
  99. package/src/graphql/mutations/publishEvent.mutation.ts +6 -5
  100. package/src/graphql/mutations/publishSeason.mutation.ts +68 -0
  101. package/src/graphql/mutations/updateEvent.mutation.ts +4 -3
  102. package/src/graphql/mutations/updateOrganization.mutation.ts +3 -2
  103. package/src/graphql/mutations/updateSeason.mutation.ts +67 -0
  104. package/src/graphql/queries/event.query.ts +2 -0
  105. package/src/graphql/queries/events.query.ts +1 -0
  106. package/src/graphql/queries/organizations.query.ts +1 -0
  107. package/src/graphql/queries/profile.query.ts +3 -0
  108. package/src/graphql/queries/profiles.query.ts +1 -0
  109. package/src/graphql/queries/publicEvent.query.ts +1 -0
  110. package/src/graphql/queries/season.query.ts +72 -0
  111. package/src/graphql/queries/seasons.query.ts +68 -0
  112. package/src/interfaces/IAnalytics.ts +1 -0
  113. package/src/interfaces/ICreateOrderParams.ts +10 -7
  114. package/src/interfaces/IEvent.ts +1 -0
  115. package/src/interfaces/IFee.ts +12 -11
  116. package/src/interfaces/IOrder.ts +4 -2
  117. package/src/interfaces/IOrderQuery.ts +2 -0
  118. package/src/interfaces/IOrganization.ts +1 -0
  119. package/src/interfaces/ISeason.ts +87 -0
  120. package/src/interfaces/ISeasonCustomField.ts +14 -0
  121. package/src/interfaces/ISeasonQuery.ts +25 -0
  122. package/src/interfaces/ISeasonUpgrade.ts +16 -0
  123. package/src/proto/broadcast.proto +29 -0
  124. package/src/proto/email.proto +39 -0
  125. package/src/proto/event.proto +4 -0
  126. package/src/proto/fee.proto +2 -0
  127. package/src/proto/order.proto +59 -0
  128. package/src/proto/organization.proto +1 -0
  129. package/src/proto/season.proto +172 -0
  130. package/src/proto/seating.proto +16 -0
  131. package/src/proto/user.proto +1 -0
  132. package/src/schemas/Event.ts +4 -0
  133. package/src/schemas/Fee.ts +4 -0
  134. package/src/schemas/Order.ts +8 -1
  135. package/src/schemas/Organization.ts +5 -0
  136. package/src/schemas/Season.ts +507 -0
  137. package/src/utils/EventUtil.ts +47 -27
  138. package/src/utils/FeeUtil.ts +25 -17
  139. package/src/utils/SeasonUtil.ts +353 -0
@@ -4,7 +4,7 @@ import IFee from "src/interfaces/IFee";
4
4
  export default {
5
5
  processingFees(fees: any[] = []) {
6
6
  return fees.filter((fee) => {
7
- if (fee.appliedBy === 'Sellout' || fee.appliedBy === 'Stripe') {
7
+ if (fee.appliedBy === "Sellout" || fee.appliedBy === "Stripe") {
8
8
  return true;
9
9
  }
10
10
  return false;
@@ -12,7 +12,7 @@ export default {
12
12
  },
13
13
  selloutFees(fees: any[] = []) {
14
14
  return fees.filter((fee) => {
15
- if (fee.appliedBy === 'Sellout') {
15
+ if (fee.appliedBy === "Sellout") {
16
16
  return true;
17
17
  }
18
18
  return false;
@@ -20,15 +20,15 @@ export default {
20
20
  },
21
21
  stripeFees(fees: any[] = []) {
22
22
  return fees.filter((fee) => {
23
- if (fee.appliedBy === 'Stripe') {
23
+ if (fee.appliedBy === "Stripe") {
24
24
  return false;
25
25
  }
26
26
  return true;
27
27
  });
28
28
  },
29
29
  promoterFees(fees: any[] = []) {
30
- return fees.filter((fee) => {
31
- if (fee.appliedBy === 'Sellout' || fee.appliedBy === 'Stripe') {
30
+ return fees?.filter((fee) => {
31
+ if (fee.appliedBy === "Sellout" || fee.appliedBy === "Stripe") {
32
32
  return false;
33
33
  }
34
34
  return true;
@@ -37,7 +37,7 @@ export default {
37
37
 
38
38
  taxFees(fees: any[] = []) {
39
39
  return fees.filter((fee) => {
40
- if (fee.name.toLowerCase() === 'sales tax') {
40
+ if (fee.name.toLowerCase() === "sales tax") {
41
41
  return true;
42
42
  }
43
43
  return false;
@@ -45,19 +45,27 @@ export default {
45
45
  },
46
46
  /****************************************************************************************
47
47
  * Fee validate
48
- ****************************************************************************************/
48
+ ****************************************************************************************/
49
49
  validateFee(fee: IFee): any {
50
50
  let feeSchema;
51
- feeSchema = Joi.object().options({ abortEarly: false }).keys({
52
- name: Joi.string().required().messages({ 'string.empty': '"Fee Name" is a required field.' }),
53
- type: Joi.string().required(),
54
- value: Joi.number().required().min(1).messages({ 'number.required': '"Price" is a required field.', "number.min": '"Price" must be greater than 0.' }),
55
- appliedTo: Joi.string().required(),
56
- minAppliedToPrice: Joi.number().optional(),
57
- maxAppliedToPrice: Joi.number().optional(),
58
- filters: Joi.array().items(Joi.string()).default([]),
59
- appliedBy: Joi.string().required(),
60
- }).unknown(true);
51
+ feeSchema = Joi.object()
52
+ .options({ abortEarly: false })
53
+ .keys({
54
+ name: Joi.string()
55
+ .required()
56
+ .messages({ "string.empty": '"Fee Name" is a required field.' }),
57
+ type: Joi.string().required(),
58
+ value: Joi.number().required().min(1).messages({
59
+ "number.required": '"Price" is a required field.',
60
+ "number.min": '"Price" must be greater than 0.',
61
+ }),
62
+ appliedTo: Joi.string().required(),
63
+ minAppliedToPrice: Joi.number().optional(),
64
+ maxAppliedToPrice: Joi.number().optional(),
65
+ filters: Joi.array().items(Joi.string()).default([]),
66
+ appliedBy: Joi.string().required(),
67
+ })
68
+ .unknown(true);
61
69
  return feeSchema.validate(fee);
62
70
  },
63
71
  };
@@ -0,0 +1,353 @@
1
+ import Joi from "@hapi/joi";
2
+ import IEventUpgrade from "../interfaces/IEventUpgrade";
3
+ import IEventPromotion from "../interfaces/IEventPromotion";
4
+ import { EventPromotionTypeEnum } from "../interfaces/IEventPromotion";
5
+ import * as Time from "@sellout/utils/.dist/time";
6
+ import ISeason from "../interfaces/ISeason";
7
+ import ITicketType from "../interfaces/ITicketType";
8
+ import ISeasonCustomField from "../interfaces/ISeasonCustomField";
9
+
10
+ export default {
11
+ /****************************************************************************************
12
+ * Tickets
13
+ ****************************************************************************************/
14
+ ticketType(season, ticketTypeId): any {
15
+ return season.ticketTypes.find(
16
+ (ticketType) => ticketType._id === ticketTypeId
17
+ );
18
+ },
19
+ activeTicketTypes(season: ISeason): ITicketType[] {
20
+ return season.ticketTypes?.filter((ticketType) => ticketType.visible) ?? [];
21
+ },
22
+ remainingTicketQty(season, ticketTypeId: string | null = null): number {
23
+ if (ticketTypeId) {
24
+ let ticketType = season.ticketTypes.find(
25
+ (ticketType) => ticketType._id === ticketTypeId
26
+ );
27
+ if (!ticketType) return 0;
28
+ else return ticketType.remainingQty;
29
+ } else {
30
+ return season.ticketTypes.reduce((cur, next) => {
31
+ return cur + next.remainingQty;
32
+ }, 0);
33
+ }
34
+ },
35
+ remainingQtyByTicketTypes(season): object {
36
+ return season.ticketTypes.reduce((cur, ticketType) => {
37
+ cur[ticketType._id] = this.remainingTicketQty(season, ticketType._id);
38
+ return cur;
39
+ }, {});
40
+ },
41
+ purchaseLimitByTicketTypes(season): object {
42
+ return season.ticketTypes.reduce((cur, ticketType) => {
43
+ cur[ticketType._id] = ticketType.purchaseLimit;
44
+ return cur;
45
+ }, {});
46
+ },
47
+ getCurrentTierId(season, ticketTypeId: string): string {
48
+ const ticketType = season.ticketTypes.find(
49
+ (t) => t._id.toString() === ticketTypeId
50
+ );
51
+ const now = Time.now();
52
+ const tier = ticketType.tiers.find(
53
+ (tier) => tier.startsAt < now && now < tier.endsAt
54
+ );
55
+ return tier._id;
56
+ },
57
+
58
+ /****************************************************************************************
59
+ * Upgrades
60
+ ****************************************************************************************/
61
+ upgrade(season, upgradeId): any {
62
+ return season?.upgrades?.find((upgrades) => upgrades._id === upgradeId);
63
+ },
64
+ /****************************************************************************************
65
+ * Upgrade validate
66
+ ****************************************************************************************/
67
+ validateUpgrade(upgrade: IEventUpgrade, isPaid: Boolean): any {
68
+ let upgradeSchema;
69
+ let limit = isPaid ? "Purchase limit" : "RSVP limit";
70
+ let used = upgrade.totalQty - upgrade.remainingQty;
71
+ upgradeSchema = Joi.object()
72
+ .options({ abortEarly: false })
73
+ .keys({
74
+ name: Joi.string()
75
+ .required()
76
+ .messages({ "string.empty": '"Upgrade name" is a required field' }),
77
+ price: Joi.number().required(),
78
+ totalQty: Joi.number()
79
+ .custom((value, helpers) => {
80
+ if (value > 0 && value < used) {
81
+ return helpers.error("totalqty.invalid");
82
+ }
83
+ return value;
84
+ })
85
+ .messages({
86
+ "totalqty.invalid":
87
+ '"Total qty." must be greater than or equal to number of upgrade sold',
88
+ })
89
+ .required()
90
+ .min(1)
91
+ .messages({
92
+ "number.required": '"Total qty." is a required field',
93
+ "number.min": '"Total qty." must be greater than 0',
94
+ }),
95
+ remainingQty: Joi.number(),
96
+ purchaseLimit: Joi.number()
97
+ .required()
98
+ .min(1)
99
+ .messages({
100
+ "number.required": `"${limit}" is a required field`,
101
+ "number.min": `"${limit}" must be greater than 0`,
102
+ "number.base": `"${limit}" must be a number`,
103
+ }),
104
+ complimentary: Joi.boolean().required(),
105
+ complimentaryWith: Joi.string().required(),
106
+ complimentaryQty: Joi.number().required(),
107
+ ticketTypeIds: Joi.array().items(Joi.string()).default([]),
108
+ imageUrl: Joi.string().optional().allow(""),
109
+ description: Joi.string().optional().allow(""),
110
+ visible: Joi.boolean().required(),
111
+ rollFees: Joi.boolean().required(),
112
+ })
113
+ .unknown(true);
114
+ return upgradeSchema.validate(upgrade);
115
+ },
116
+ /****************************************************************************************
117
+ * Venue
118
+ ****************************************************************************************/
119
+ venueIds(season): string[] {
120
+ let venueIds = [season.venueId];
121
+ season.performances.forEach((performance) => {
122
+ venueIds = venueIds.concat(performance.venueStageId);
123
+ });
124
+ venueIds = [...new Set(venueIds)];
125
+ venueIds = venueIds.filter((v) => !!v);
126
+ return venueIds;
127
+ },
128
+ seatingId(season): string {
129
+ return season._id.replace("_", "SAMH");
130
+ },
131
+ /****************************************************************************************
132
+ * Promotions
133
+ ****************************************************************************************/
134
+ promotion(season, promotionId: string): any {
135
+ return season?.promotions?.find(
136
+ (promotions) => promotions._id === promotionId
137
+ );
138
+ },
139
+ activePromotions(
140
+ season?: ISeason,
141
+ type: EventPromotionTypeEnum | null = null
142
+ ): IEventPromotion[] {
143
+ const now = Time.now();
144
+
145
+ let promotions = (season?.promotions ?? [])
146
+ // must be active
147
+ .filter((promotion) => promotion.active)
148
+ // must have remaining qty
149
+ .filter((promotion) => promotion.remainingQty > 0)
150
+ // must be in the correct time
151
+ .filter(
152
+ (promotion) => promotion.startsAt < now && now < promotion.endsAt
153
+ );
154
+
155
+ // Optional type
156
+ if (type !== null) {
157
+ promotions = promotions.filter((promotion) => promotion.type === type);
158
+ }
159
+
160
+ return promotions;
161
+ },
162
+ // /****************************************************************************************
163
+ // * Validate Publish
164
+ // ****************************************************************************************/
165
+ validatePublish(season: ISeason): any {
166
+ let seasonSchema;
167
+ // switch (season.type) {
168
+ // case SeasonTypeEnum.GeneralEvent:
169
+ seasonSchema = Joi.object()
170
+ .options({ abortEarly: false })
171
+ .keys({
172
+ name: Joi.string()
173
+ .required()
174
+ .messages({ "string.empty": '"Season name" is a required field' }),
175
+ description: Joi.string().required().messages({
176
+ "string.empty": '"Season description" is a required field',
177
+ }),
178
+ posterImageUrl: Joi.string().required().messages({
179
+ "string.empty": '"Season image" is a required field',
180
+ }),
181
+ venueId: Joi.string()
182
+ .required()
183
+ .messages({ "string.empty": '"Venue" is required' }),
184
+ ticketTypes: Joi.array()
185
+ .min(1)
186
+ .messages({ "array.min": '"Season" must have atleast 1 ticket' }),
187
+ })
188
+ .unknown(true);
189
+
190
+ return seasonSchema.validate(season);
191
+ },
192
+
193
+ /****************************************************************************************
194
+ * Custom Fields
195
+ ****************************************************************************************/
196
+ customField(
197
+ season: ISeason,
198
+ customFieldId: string
199
+ ): ISeasonCustomField | null {
200
+ return (
201
+ season?.customFields?.find(
202
+ (customField) => customField._id === customFieldId
203
+ ) ?? null
204
+ );
205
+ },
206
+
207
+ activeCustomFields(season: ISeason): ISeasonCustomField[] {
208
+ return (
209
+ season?.customFields?.filter((customField) => customField.active) ?? []
210
+ );
211
+ },
212
+ /****************************************************************************************
213
+ * Seating
214
+ ****************************************************************************************/
215
+ isSeated(season?: ISeason): boolean {
216
+ if (!season) return false;
217
+ return Boolean(season.seatingChartKey);
218
+ },
219
+
220
+ /****************************************************************************************
221
+ * Artist
222
+ ****************************************************************************************/
223
+ artistIds(season): string[] {
224
+ let artistIds = [];
225
+ season.performances.forEach((performance) => {
226
+ artistIds = artistIds
227
+ .concat(performance.headliningArtistIds)
228
+ .concat(performance.openingArtistIds);
229
+ });
230
+ artistIds = [...new Set(artistIds)];
231
+ artistIds = artistIds.filter((a) => !!a);
232
+ return artistIds;
233
+ },
234
+ /****************************************************************************************
235
+ * Promotion validate
236
+ ****************************************************************************************/
237
+ validatePromotion(promotion: IEventPromotion): any {
238
+ let promotionSchema;
239
+ let used = promotion.totalQty - promotion.remainingQty;
240
+ promotionSchema = Joi.object()
241
+ .options({ abortEarly: false })
242
+ .keys({
243
+ code: Joi.string()
244
+ .required()
245
+ .messages({ "string.empty": '"Secret code" is a required field' }),
246
+ type: Joi.string().required(),
247
+ remainingQty: Joi.number(),
248
+ totalQty: Joi.number()
249
+ .custom((value, helpers) => {
250
+ if (value > 0 && value < used) {
251
+ return helpers.error("totalqty.invalid");
252
+ }
253
+ return value;
254
+ })
255
+ .messages({
256
+ "totalqty.invalid":
257
+ '"Total qty." must be greater than or equal to number of secret code sold',
258
+ })
259
+ .required()
260
+ .min(1)
261
+ .messages({
262
+ "number.required": '"Total qty." is a required field',
263
+ "number.min": '"Total qty." must be greater than 0',
264
+ }),
265
+ ticketTypeIds: Joi.array().items(Joi.string()).default([]),
266
+ upgradeIds: Joi.array().items(Joi.string()).default([]),
267
+ active: Joi.boolean().required(),
268
+ startsAt: Joi.number().required(),
269
+ endsAt: Joi.number().required(),
270
+ useLimit: Joi.number().min(1).messages({
271
+ "number.required": '"Use limit" is a required field',
272
+ "number.min": 'Use limit" must be greater than 0',
273
+ "number.base": '"Use limit" must be a number',
274
+ }),
275
+ discountType: Joi.string(),
276
+ discountValue: Joi.number(),
277
+ })
278
+ .unknown(true);
279
+ return promotionSchema.validate(promotion);
280
+ },
281
+ /****************************************************************************************
282
+ * Schedule
283
+ ****************************************************************************************/
284
+ hasBeenAnnounced(season): boolean {
285
+ const {
286
+ schedule: { announceAt },
287
+ } = season;
288
+ const now = Time.now();
289
+ return announceAt < now;
290
+ },
291
+ isAnnounced(season): boolean {
292
+ const {
293
+ schedule: { announceAt, ticketsAt },
294
+ } = season;
295
+ const now = Time.now();
296
+ return announceAt < now && now < ticketsAt;
297
+ },
298
+ isOnSale(season): boolean {
299
+ const {
300
+ schedule: { ticketsAt, ticketsEndAt },
301
+ } = season;
302
+ const now = Time.now();
303
+ return ticketsAt < now && now < ticketsEndAt;
304
+ },
305
+ isInProgress(season): boolean {
306
+ const {
307
+ schedule: { startsAt, endsAt },
308
+ } = season;
309
+ const now = Time.now();
310
+ return startsAt < now && now < endsAt;
311
+ },
312
+ saleHasEnded(season): boolean {
313
+ const {
314
+ schedule: { ticketsEndAt },
315
+ } = season;
316
+ const now = Time.now();
317
+ return ticketsEndAt < now;
318
+ },
319
+ isSoldOut(season?: ISeason): boolean {
320
+ return this.remainingTicketQty(season) > 0;
321
+ },
322
+ hasEnded(season): boolean {
323
+ const {
324
+ schedule: { endsAt },
325
+ } = season;
326
+ const now = Time.now();
327
+ return endsAt < now;
328
+ },
329
+ isUnavailable(season?: ISeason): boolean {
330
+ if (!season?.published) return true;
331
+ if (!this.hasBeenAnnounced(season)) return true;
332
+ if (!this.isOnSale(season)) return true;
333
+ if (this.allTicketsAreLocked(season)) return true;
334
+ if (this.saleHasEnded(season)) return true;
335
+ return false;
336
+ },
337
+ allTicketsAreLocked(season?: ISeason): boolean {
338
+ const ticketTypeCount = season?.ticketTypes?.length;
339
+ const promotionCodeTicketCount = [
340
+ ...new Set(
341
+ season?.promotions
342
+ ?.filter((a) => a.type === "Unlock")
343
+ .reduce((cur: string[], promotion) => {
344
+ // (this.isOnSale(season) ? promotion.type === "Unlock" : (promotion.type === "Presale" || promotion.type === "Unlock"))
345
+ // if(2!==2)
346
+ return [...cur, ...promotion.ticketTypeIds];
347
+ }, [])
348
+ ),
349
+ ].length;
350
+
351
+ return ticketTypeCount === promotionCodeTicketCount;
352
+ },
353
+ };