@sellout/models 0.0.435 → 0.0.437
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/order.fragment.js +1 -0
- package/.dist/graphql/fragments/order.fragment.js.map +1 -1
- package/.dist/graphql/mutations/batchPrintBreakApartOrder.mutation.js +1 -0
- package/.dist/graphql/mutations/batchPrintBreakApartOrder.mutation.js.map +1 -1
- package/.dist/graphql/mutations/breakApartOrder.js +1 -0
- package/.dist/graphql/mutations/breakApartOrder.js.map +1 -1
- package/.dist/graphql/mutations/createEvent.mutation.js +1 -0
- package/.dist/graphql/mutations/createEvent.mutation.js.map +1 -1
- package/.dist/graphql/mutations/duplicateEvent.mutation.js +1 -0
- package/.dist/graphql/mutations/duplicateEvent.mutation.js.map +1 -1
- package/.dist/graphql/mutations/multipleBreakApartOrder.mutation.js +1 -0
- package/.dist/graphql/mutations/multipleBreakApartOrder.mutation.js.map +1 -1
- package/.dist/graphql/mutations/publishEvent.mutation.js +1 -0
- package/.dist/graphql/mutations/publishEvent.mutation.js.map +1 -1
- package/.dist/graphql/mutations/updateEvent.mutation.js +1 -0
- package/.dist/graphql/mutations/updateEvent.mutation.js.map +1 -1
- package/.dist/graphql/queries/event.query.js +1 -0
- package/.dist/graphql/queries/event.query.js.map +1 -1
- package/.dist/graphql/queries/order.query.js +1 -0
- package/.dist/graphql/queries/order.query.js.map +1 -1
- package/.dist/graphql/queries/orders.query.js +1 -0
- package/.dist/graphql/queries/orders.query.js.map +1 -1
- package/.dist/graphql/queries/ordersTableOptimized.query.js +2 -0
- package/.dist/graphql/queries/ordersTableOptimized.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/interfaces/IEvent.d.ts +5 -0
- package/.dist/interfaces/IEvent.js +6 -1
- package/.dist/interfaces/IEvent.js.map +1 -1
- package/.dist/interfaces/IScan.d.ts +1 -0
- package/.dist/schemas/Event.d.ts +6 -1
- package/.dist/schemas/Event.js +5 -0
- package/.dist/schemas/Event.js.map +1 -1
- package/.dist/schemas/Order.d.ts +8 -0
- package/.dist/schemas/Order.js +3 -0
- package/.dist/schemas/Order.js.map +1 -1
- package/.dist/sellout-proto.js +110 -0
- package/.dist/utils/EventUtil.d.ts +12 -0
- package/.dist/utils/EventUtil.js +88 -0
- package/.dist/utils/EventUtil.js.map +1 -1
- package/package.json +3 -3
- package/src/graphql/fragments/order.fragment.ts +1 -0
- package/src/graphql/mutations/batchPrintBreakApartOrder.mutation.ts +1 -0
- package/src/graphql/mutations/breakApartOrder.ts +1 -0
- package/src/graphql/mutations/createEvent.mutation.ts +1 -0
- package/src/graphql/mutations/duplicateEvent.mutation.ts +1 -0
- package/src/graphql/mutations/multipleBreakApartOrder.mutation.ts +1 -0
- package/src/graphql/mutations/publishEvent.mutation.ts +1 -0
- package/src/graphql/mutations/updateEvent.mutation.ts +1 -0
- package/src/graphql/queries/event.query.ts +1 -0
- package/src/graphql/queries/order.query.ts +1 -0
- package/src/graphql/queries/orders.query.ts +1 -0
- package/src/graphql/queries/ordersTableOptimized.query.ts +2 -0
- package/src/graphql/queries/publicEvent.query.ts +1 -0
- package/src/interfaces/IEvent.ts +6 -0
- package/src/interfaces/IScan.ts +1 -0
- package/src/proto/event.proto +3 -0
- package/src/proto/order.proto +2 -0
- package/src/schemas/Event.ts +6 -1
- package/src/schemas/Order.ts +3 -0
- package/src/utils/EventUtil.ts +114 -0
package/src/interfaces/IEvent.ts
CHANGED
|
@@ -52,6 +52,11 @@ export enum MultidayEventDates {
|
|
|
52
52
|
DaySeven = "7"
|
|
53
53
|
|
|
54
54
|
}
|
|
55
|
+
export enum MultiDayEntryEnum {
|
|
56
|
+
Single = "Single",
|
|
57
|
+
Daily = "Daily",
|
|
58
|
+
}
|
|
59
|
+
|
|
55
60
|
export enum EventTicketDelivery {
|
|
56
61
|
Digital = "Digital only",
|
|
57
62
|
Physical = "Will-call only",
|
|
@@ -112,6 +117,7 @@ export default interface IEvent {
|
|
|
112
117
|
salesBeginImmediately?: boolean;
|
|
113
118
|
isMultipleDays?: boolean;
|
|
114
119
|
totalDays?: MultidayEventDates;
|
|
120
|
+
multiDayEntry?: MultiDayEntryEnum;
|
|
115
121
|
cancel?: boolean;
|
|
116
122
|
fees: IFee[];
|
|
117
123
|
seasonId?: string;
|
package/src/interfaces/IScan.ts
CHANGED
package/src/proto/event.proto
CHANGED
|
@@ -56,6 +56,7 @@ message Event {
|
|
|
56
56
|
repeated string additionalPhotos = 48;
|
|
57
57
|
repeated string tagIds = 49;
|
|
58
58
|
repeated GuestListEntry guestList = 50;
|
|
59
|
+
string multiDayEntry = 51;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
message PublicEvent {
|
|
@@ -999,6 +1000,8 @@ message MobileCheckInEvent {
|
|
|
999
1000
|
string userAgreement = 9;
|
|
1000
1001
|
repeated EventCustomFields customFields = 10;
|
|
1001
1002
|
repeated MobileCheckInGuestListEntry guestList = 11;
|
|
1003
|
+
bool isMultipleDays = 12;
|
|
1004
|
+
string multiDayEntry = 13;
|
|
1002
1005
|
}
|
|
1003
1006
|
|
|
1004
1007
|
message MobileCheckInHoldTicketRequest {
|
package/src/proto/order.proto
CHANGED
|
@@ -162,6 +162,7 @@ message Scan {
|
|
|
162
162
|
string scannedBy = 2;
|
|
163
163
|
int32 startsAt = 3;
|
|
164
164
|
string scannerName = 4;
|
|
165
|
+
int32 endsAt = 5;
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
message Refund {
|
|
@@ -1066,6 +1067,7 @@ message MobileCheckInScan {
|
|
|
1066
1067
|
bool scanned = 1;
|
|
1067
1068
|
int32 scannedAt = 2;
|
|
1068
1069
|
int32 startsAt = 3;
|
|
1070
|
+
int32 endsAt = 4;
|
|
1069
1071
|
}
|
|
1070
1072
|
|
|
1071
1073
|
message MobileCheckInTicket {
|
package/src/schemas/Event.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import shortid from 'shortid';
|
|
2
|
-
import { EventAgeEnum, SendQRCodeEnum, EventProcessAsEnum, EventTicketDelivery } from '../interfaces/IEvent';
|
|
2
|
+
import { EventAgeEnum, SendQRCodeEnum, EventProcessAsEnum, EventTicketDelivery, MultiDayEntryEnum } from '../interfaces/IEvent';
|
|
3
3
|
import { UpgradeTypeComplimentaryWithEnum } from "../interfaces/IEventUpgrade";
|
|
4
4
|
import Address from './Address';
|
|
5
5
|
import Metrics from './Metrics';
|
|
@@ -642,6 +642,11 @@ export default {
|
|
|
642
642
|
required: true,
|
|
643
643
|
default: false
|
|
644
644
|
},
|
|
645
|
+
multiDayEntry: {
|
|
646
|
+
type: String,
|
|
647
|
+
required: false,
|
|
648
|
+
default: MultiDayEntryEnum.Daily
|
|
649
|
+
},
|
|
645
650
|
age: {
|
|
646
651
|
type: String,
|
|
647
652
|
required: true,
|
package/src/schemas/Order.ts
CHANGED
package/src/utils/EventUtil.ts
CHANGED
|
@@ -5,6 +5,7 @@ import IRefundModal from "../interfaces/IRefundModal";
|
|
|
5
5
|
import IEvent, {
|
|
6
6
|
EventProcessAsEnum,
|
|
7
7
|
EventTypeEnum,
|
|
8
|
+
MultiDayEntryEnum,
|
|
8
9
|
} from "../interfaces/IEvent";
|
|
9
10
|
import { CustomFieldTypeEnum } from "../enums/CustomFieldTypeEnum";
|
|
10
11
|
import IOrderCustomField from "../interfaces/IOrderCustomField";
|
|
@@ -20,6 +21,7 @@ import IGuestListEntry from "../interfaces/IGuestListEntry";
|
|
|
20
21
|
import IGuestListCheckIn from "../interfaces/IGuestListCheckIn";
|
|
21
22
|
import IGuestListSession from "../interfaces/IGuestListSession";
|
|
22
23
|
import IEmailHolders from "../interfaces/IEmailHolders";
|
|
24
|
+
import IScan from "../interfaces/IScan";
|
|
23
25
|
|
|
24
26
|
export default {
|
|
25
27
|
/****************************************************************************************
|
|
@@ -255,6 +257,46 @@ export default {
|
|
|
255
257
|
},
|
|
256
258
|
|
|
257
259
|
guestListSessions(event: IEvent): IGuestListSession[] {
|
|
260
|
+
const sessions = this.scheduleSessions(event);
|
|
261
|
+
|
|
262
|
+
if (!this.isSingleEntry(event) || sessions.length < 2) return sessions;
|
|
263
|
+
|
|
264
|
+
// Single entry: one check-in covers the whole event, the same as tickets,
|
|
265
|
+
// so the guest is checked in once and stays checked in for the rest.
|
|
266
|
+
return [this.eventSession(event) as IGuestListSession];
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
// The whole event as one session: the first day's start to the latest end.
|
|
270
|
+
eventSession(event: IEvent): IGuestListSession | null {
|
|
271
|
+
const sessions = this.scheduleSessions(event);
|
|
272
|
+
|
|
273
|
+
if (!sessions.length) return null;
|
|
274
|
+
|
|
275
|
+
const endsAt = sessions
|
|
276
|
+
.map((session) => session.endsAt)
|
|
277
|
+
.filter((value): value is number => Boolean(value));
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
startsAt: sessions[0].startsAt,
|
|
281
|
+
endsAt: endsAt.length ? Math.max(...endsAt) : null,
|
|
282
|
+
};
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
// When single-entry check-in opens: doors on the first day, or the first
|
|
286
|
+
// start time when no doors time is set.
|
|
287
|
+
eventCheckInOpensAt(event: IEvent): number | null {
|
|
288
|
+
const session = this.eventSession(event);
|
|
289
|
+
|
|
290
|
+
if (!session) return null;
|
|
291
|
+
|
|
292
|
+
const doorsAt = (event?.performances?.[0]?.schedule ?? [])
|
|
293
|
+
.filter((day) => day?.startsAt === session.startsAt && day?.doorsAt)
|
|
294
|
+
.map((day) => day.doorsAt as number);
|
|
295
|
+
|
|
296
|
+
return Math.min(session.startsAt, ...doorsAt);
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
scheduleSessions(event: IEvent): IGuestListSession[] {
|
|
258
300
|
const scheduled = (event?.performances?.[0]?.schedule ?? [])
|
|
259
301
|
.filter((day) => Boolean(day?.startsAt))
|
|
260
302
|
.map((day) => ({
|
|
@@ -291,6 +333,67 @@ export default {
|
|
|
291
333
|
: [];
|
|
292
334
|
},
|
|
293
335
|
|
|
336
|
+
/****************************************************************************************
|
|
337
|
+
* Multi-day Entry
|
|
338
|
+
****************************************************************************************/
|
|
339
|
+
|
|
340
|
+
isSingleEntry(event: IEvent): boolean {
|
|
341
|
+
return (
|
|
342
|
+
Boolean(event?.isMultipleDays) &&
|
|
343
|
+
event?.multiDayEntry === MultiDayEntryEnum.Single
|
|
344
|
+
);
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
// Daily: one scan per day the ticket is valid for. Single: one scan for the
|
|
348
|
+
// whole event, whatever days the ticket covers. The client treats it as a
|
|
349
|
+
// registration-desk check-in, open from the first day to the last.
|
|
350
|
+
ticketScans(event: IEvent, dayIds: string[] = []): IScan[] {
|
|
351
|
+
const unscanned = { scanned: false, scannedAt: 0, scannedBy: "" };
|
|
352
|
+
|
|
353
|
+
if (!this.isSingleEntry(event)) {
|
|
354
|
+
if (!dayIds?.length) {
|
|
355
|
+
return [{ ...unscanned, startsAt: event?.schedule?.startsAt }];
|
|
356
|
+
}
|
|
357
|
+
return dayIds.map((day) => ({ ...unscanned, startsAt: parseInt(day) }));
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const session = this.eventSession(event);
|
|
361
|
+
|
|
362
|
+
return [
|
|
363
|
+
{
|
|
364
|
+
...unscanned,
|
|
365
|
+
startsAt:
|
|
366
|
+
this.eventCheckInOpensAt(event) ?? event?.schedule?.startsAt,
|
|
367
|
+
endsAt: session?.endsAt ?? event?.schedule?.endsAt ?? undefined,
|
|
368
|
+
},
|
|
369
|
+
];
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
// The days a ticket gets its own entry for (day-of reminder, printed ticket):
|
|
373
|
+
// every day for Daily, only the event's first day for Single.
|
|
374
|
+
entryDays(event: IEvent, dayIds: string[] = []): string[] {
|
|
375
|
+
if (!this.isSingleEntry(event) || !dayIds?.length) return dayIds ?? [];
|
|
376
|
+
const session = this.eventSession(event);
|
|
377
|
+
return session ? [String(session.startsAt)] : dayIds.slice(0, 1);
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
// A daily scan is valid on its own calendar day. A single-entry scan is valid
|
|
381
|
+
// from doors on the first day (its startsAt) to the end of the last day.
|
|
382
|
+
scanIsValidOn(scan: IScan, at: number, timezone: string): boolean {
|
|
383
|
+
if (!scan?.startsAt) return false;
|
|
384
|
+
|
|
385
|
+
if (scan.endsAt) return scan.startsAt <= at && at <= scan.endsAt;
|
|
386
|
+
|
|
387
|
+
const day = (seconds: number) =>
|
|
388
|
+
Time.format(seconds, "YYYY-MM-DD", timezone);
|
|
389
|
+
return day(scan.startsAt) === day(at);
|
|
390
|
+
},
|
|
391
|
+
|
|
392
|
+
// A single-entry scan that was never used and whose window is over.
|
|
393
|
+
scanIsClosed(scan: IScan, at: number): boolean {
|
|
394
|
+
return Boolean(scan?.endsAt) && at > (scan.endsAt as number);
|
|
395
|
+
},
|
|
396
|
+
|
|
294
397
|
GUEST_LIST_MAX_GROUP_SIZE: 100,
|
|
295
398
|
guestListHighestNumber(
|
|
296
399
|
guestList: IGuestListEntry[],
|
|
@@ -405,6 +508,17 @@ export default {
|
|
|
405
508
|
timezone: string,
|
|
406
509
|
at: number = Time.now()
|
|
407
510
|
): number | null {
|
|
511
|
+
// Single entry: guests check in from doors on the first day to the end of
|
|
512
|
+
// the last day, the same window as tickets.
|
|
513
|
+
if (this.isSingleEntry(event)) {
|
|
514
|
+
const session = this.eventSession(event);
|
|
515
|
+
const opensAt = this.eventCheckInOpensAt(event);
|
|
516
|
+
|
|
517
|
+
if (session?.endsAt && opensAt !== null) {
|
|
518
|
+
return opensAt <= at && at <= session.endsAt ? session.startsAt : null;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
408
522
|
const day = (seconds: number) => Time.format(seconds, "YYYY-MM-DD", timezone);
|
|
409
523
|
const today = day(at);
|
|
410
524
|
const sessions = this.guestListSessions(event);
|