@sellout/models 0.0.151 → 0.0.153
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/graphql/fragments/season.fragment.d.ts +23 -0
- package/.dist/graphql/fragments/season.fragment.js +315 -0
- package/.dist/graphql/fragments/season.fragment.js.map +1 -0
- package/.dist/graphql/mutations/createEvent.mutation.js +1 -0
- package/.dist/graphql/mutations/createEvent.mutation.js.map +1 -1
- package/.dist/graphql/mutations/createFee.mutation.js +1 -0
- package/.dist/graphql/mutations/createFee.mutation.js.map +1 -1
- package/.dist/graphql/mutations/createSeason.mutation.d.ts +2 -0
- package/.dist/graphql/mutations/createSeason.mutation.js +72 -0
- package/.dist/graphql/mutations/createSeason.mutation.js.map +1 -0
- package/.dist/graphql/mutations/createSeasonOrder.mutation.d.ts +2 -0
- package/.dist/graphql/mutations/createSeasonOrder.mutation.js +65 -0
- package/.dist/graphql/mutations/createSeasonOrder.mutation.js.map +1 -0
- package/.dist/graphql/mutations/createSeasonOrderPaymentIntent.mutation.d.ts +2 -0
- package/.dist/graphql/mutations/createSeasonOrderPaymentIntent.mutation.js +18 -0
- package/.dist/graphql/mutations/createSeasonOrderPaymentIntent.mutation.js.map +1 -0
- package/.dist/graphql/mutations/publishEvent.mutation.js +6 -5
- package/.dist/graphql/mutations/publishEvent.mutation.js.map +1 -1
- package/.dist/graphql/mutations/publishSeason.mutation.d.ts +2 -0
- package/.dist/graphql/mutations/publishSeason.mutation.js +72 -0
- package/.dist/graphql/mutations/publishSeason.mutation.js.map +1 -0
- package/.dist/graphql/mutations/updateEvent.mutation.js +2 -1
- package/.dist/graphql/mutations/updateEvent.mutation.js.map +1 -1
- package/.dist/graphql/mutations/updateOrganization.mutation.js +1 -0
- package/.dist/graphql/mutations/updateOrganization.mutation.js.map +1 -1
- package/.dist/graphql/mutations/updateSeason.mutation.d.ts +2 -0
- package/.dist/graphql/mutations/updateSeason.mutation.js +71 -0
- package/.dist/graphql/mutations/updateSeason.mutation.js.map +1 -0
- package/.dist/graphql/queries/event.query.js +2 -0
- package/.dist/graphql/queries/event.query.js.map +1 -1
- package/.dist/graphql/queries/events.query.js +1 -0
- package/.dist/graphql/queries/events.query.js.map +1 -1
- package/.dist/graphql/queries/order.query.js +14 -11
- package/.dist/graphql/queries/order.query.js.map +1 -1
- package/.dist/graphql/queries/orders.query.js +4 -2
- package/.dist/graphql/queries/orders.query.js.map +1 -1
- package/.dist/graphql/queries/profile.query.js +1 -0
- package/.dist/graphql/queries/profile.query.js.map +1 -1
- package/.dist/graphql/queries/promoCodeVerify.query.js +27 -23
- package/.dist/graphql/queries/promoCodeVerify.query.js.map +1 -1
- package/.dist/graphql/queries/publicEvent.query.js +1 -0
- package/.dist/graphql/queries/publicEvent.query.js.map +1 -1
- package/.dist/graphql/queries/publicSeason.query.d.ts +2 -0
- package/.dist/graphql/queries/publicSeason.query.js +76 -0
- package/.dist/graphql/queries/publicSeason.query.js.map +1 -0
- package/.dist/graphql/queries/season.query.d.ts +2 -0
- package/.dist/graphql/queries/season.query.js +73 -0
- package/.dist/graphql/queries/season.query.js.map +1 -0
- package/.dist/graphql/queries/seasons.query.d.ts +2 -0
- package/.dist/graphql/queries/seasons.query.js +72 -0
- package/.dist/graphql/queries/seasons.query.js.map +1 -0
- package/.dist/interfaces/IAnalytics.d.ts +1 -0
- package/.dist/interfaces/IAnalytics.js.map +1 -1
- package/.dist/interfaces/ICreateOrderParams.d.ts +4 -1
- package/.dist/interfaces/IEvent.d.ts +1 -0
- package/.dist/interfaces/IFee.d.ts +1 -0
- package/.dist/interfaces/IOrder.d.ts +8 -1
- package/.dist/interfaces/IOrder.js.map +1 -1
- package/.dist/interfaces/IOrderQuery.d.ts +2 -0
- package/.dist/interfaces/IOrderType.d.ts +2 -1
- package/.dist/interfaces/IOrderType.js +1 -0
- package/.dist/interfaces/IOrderType.js.map +1 -1
- package/.dist/interfaces/IOrganization.d.ts +1 -0
- package/.dist/interfaces/ISeason.d.ts +76 -0
- package/.dist/interfaces/ISeason.js +34 -0
- package/.dist/interfaces/ISeason.js.map +1 -0
- package/.dist/interfaces/ISeasonCustomField.d.ts +13 -0
- package/.dist/interfaces/ISeasonCustomField.js +3 -0
- package/.dist/interfaces/ISeasonCustomField.js.map +1 -0
- package/.dist/interfaces/ISeasonQuery.d.ts +23 -0
- package/.dist/interfaces/ISeasonQuery.js +15 -0
- package/.dist/interfaces/ISeasonQuery.js.map +1 -0
- package/.dist/interfaces/ISeasonUpgrade.d.ts +16 -0
- package/.dist/interfaces/ISeasonUpgrade.js +3 -0
- package/.dist/interfaces/ISeasonUpgrade.js.map +1 -0
- package/.dist/schemas/Event.d.ts +4 -0
- package/.dist/schemas/Event.js +4 -0
- package/.dist/schemas/Event.js.map +1 -1
- package/.dist/schemas/Fee.d.ts +5 -0
- package/.dist/schemas/Fee.js +4 -0
- package/.dist/schemas/Fee.js.map +1 -1
- package/.dist/schemas/Order.d.ts +8 -0
- package/.dist/schemas/Order.js +8 -1
- package/.dist/schemas/Order.js.map +1 -1
- package/.dist/schemas/Organization.d.ts +5 -0
- package/.dist/schemas/Organization.js +5 -0
- package/.dist/schemas/Organization.js.map +1 -1
- package/.dist/schemas/Season.d.ts +679 -0
- package/.dist/schemas/Season.js +502 -0
- package/.dist/schemas/Season.js.map +1 -0
- package/.dist/sellout-proto.js +36625 -26718
- package/.dist/utils/EventUtil.js +36 -19
- package/.dist/utils/EventUtil.js.map +1 -1
- package/.dist/utils/FeeUtil.d.ts +1 -1
- package/.dist/utils/FeeUtil.js +19 -11
- package/.dist/utils/FeeUtil.js.map +1 -1
- package/.dist/utils/SeasonUtil.d.ts +66 -0
- package/.dist/utils/SeasonUtil.js +340 -0
- package/.dist/utils/SeasonUtil.js.map +1 -0
- package/package.json +3 -3
- package/src/graphql/fragments/season.fragment.ts +336 -0
- package/src/graphql/mutations/createEvent.mutation.ts +1 -0
- package/src/graphql/mutations/createFee.mutation.ts +2 -1
- package/src/graphql/mutations/createSeason.mutation.ts +68 -0
- package/src/graphql/mutations/createSeasonOrder.mutation.ts +61 -0
- package/src/graphql/mutations/createSeasonOrderPaymentIntent.mutation.ts +14 -0
- package/src/graphql/mutations/publishEvent.mutation.ts +6 -5
- package/src/graphql/mutations/publishSeason.mutation.ts +68 -0
- package/src/graphql/mutations/updateEvent.mutation.ts +4 -3
- package/src/graphql/mutations/updateOrganization.mutation.ts +3 -2
- package/src/graphql/mutations/updateSeason.mutation.ts +67 -0
- package/src/graphql/queries/event.query.ts +2 -0
- package/src/graphql/queries/events.query.ts +1 -0
- package/src/graphql/queries/order.query.ts +15 -12
- package/src/graphql/queries/orders.query.ts +5 -3
- package/src/graphql/queries/profile.query.ts +1 -0
- package/src/graphql/queries/promoCodeVerify.query.ts +27 -23
- package/src/graphql/queries/publicEvent.query.ts +1 -0
- package/src/graphql/queries/publicSeason.query.ts +72 -0
- package/src/graphql/queries/season.query.ts +69 -0
- package/src/graphql/queries/seasons.query.ts +68 -0
- package/src/interfaces/IAnalytics.ts +1 -0
- package/src/interfaces/ICreateOrderParams.ts +10 -7
- package/src/interfaces/IEvent.ts +1 -0
- package/src/interfaces/IFee.ts +12 -11
- package/src/interfaces/IOrder.ts +11 -2
- package/src/interfaces/IOrderQuery.ts +2 -0
- package/src/interfaces/IOrderType.ts +1 -0
- package/src/interfaces/IOrganization.ts +1 -0
- package/src/interfaces/ISeason.ts +87 -0
- package/src/interfaces/ISeasonCustomField.ts +14 -0
- package/src/interfaces/ISeasonQuery.ts +25 -0
- package/src/interfaces/ISeasonUpgrade.ts +16 -0
- package/src/proto/broadcast.proto +29 -0
- package/src/proto/email.proto +39 -0
- package/src/proto/event.proto +4 -0
- package/src/proto/fee.proto +2 -0
- package/src/proto/order.proto +60 -0
- package/src/proto/organization.proto +1 -0
- package/src/proto/season.proto +172 -0
- package/src/proto/seating.proto +16 -0
- package/src/proto/user.proto +1 -0
- package/src/schemas/Event.ts +4 -0
- package/src/schemas/Fee.ts +4 -0
- package/src/schemas/Order.ts +8 -1
- package/src/schemas/Organization.ts +5 -0
- package/src/schemas/Season.ts +507 -0
- package/src/utils/EventUtil.ts +51 -31
- package/src/utils/FeeUtil.ts +25 -17
- package/src/utils/SeasonUtil.ts +353 -0
package/src/utils/FeeUtil.ts
CHANGED
|
@@ -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 ===
|
|
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 ===
|
|
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 ===
|
|
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
|
|
31
|
-
if (fee.appliedBy ===
|
|
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() ===
|
|
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()
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
+
};
|