ghostguild-org/server/api/series/[id]/tickets/available.get.js

118 lines
3.2 KiB
JavaScript

import Series from "../../../../models/series.js";
import Member from "../../../../models/member.js";
import {
calculateSeriesTicketPrice,
checkSeriesTicketAvailability,
checkUserSeriesPass,
} from "../../../../utils/tickets.js";
export default defineEventHandler(async (event) => {
try {
const seriesId = getRouterParam(event, "id");
const query = getQuery(event);
const email = query.email;
// Fetch series
// Build query conditions based on whether seriesId looks like ObjectId or string
const isObjectId = /^[0-9a-fA-F]{24}$/.test(seriesId);
const seriesQuery = isObjectId
? { $or: [{ _id: seriesId }, { id: seriesId }, { slug: seriesId }] }
: { $or: [{ id: seriesId }, { slug: seriesId }] };
const series = await Series.findOne(seriesQuery);
if (!series) {
throw createError({
statusCode: 404,
statusMessage: "Series not found",
});
}
// Check if tickets are enabled
if (!series.tickets?.enabled) {
return {
available: false,
message: "Tickets are not enabled for this series",
};
}
// Check membership if email provided
let member = null;
if (email) {
member = await Member.findOne({ email: email.toLowerCase() });
}
// Check if user already has a series pass
const { hasPass, registration } = checkUserSeriesPass(series, email || "");
if (hasPass) {
return {
available: false,
alreadyRegistered: true,
registration: {
ticketType: registration.ticketType,
registeredAt: registration.registeredAt,
eventsIncluded: registration.eventRegistrations?.length || 0,
},
message: "You already have a pass for this series",
};
}
// Calculate pricing for user
const ticketInfo = calculateSeriesTicketPrice(series, member);
if (!ticketInfo) {
return {
available: false,
message: "No series passes available for your membership status",
};
}
// Check availability
const availability = checkSeriesTicketAvailability(
series,
ticketInfo.ticketType,
);
return {
available: availability.available,
ticket: {
type: ticketInfo.ticketType,
name: ticketInfo.name,
description: ticketInfo.description,
price: ticketInfo.price,
currency: ticketInfo.currency,
isFree: ticketInfo.isFree,
isEarlyBird: ticketInfo.isEarlyBird,
},
availability: {
remaining: availability.remaining,
unlimited: availability.remaining === null,
waitlistAvailable: availability.waitlistAvailable,
},
series: {
id: series.id,
title: series.title,
totalEvents: series.totalEvents,
type: series.type,
},
memberInfo: member
? {
isMember: true,
circle: member.circle,
name: member.name,
}
: {
isMember: false,
},
};
} catch (error) {
console.error("Error checking series ticket availability:", error);
throw createError({
statusCode: error.statusCode || 500,
statusMessage:
error.statusMessage || "Failed to check series ticket availability",
});
}
});