Handballbooking/server/controllers/ticketController.js
2025-06-04 15:13:40 +02:00

156 lines
4.5 KiB
JavaScript
Executable file

import { query } from '../utils/database.js';
import { sendEmail } from '../utils/email.js';
import { generateTicketPDF } from '../utils/pdf.js';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export const createTicket = async (req, res) => {
try {
const { matchId, name, email, phone, selectedSeats, deliveryMethod } = req.body;
// Start transaction
await query('START TRANSACTION');
try {
// Check if seats are available
const seats = await query(
'SELECT * FROM seats WHERE matchId = ? AND seatNumber IN (?) AND status = "available"',
[matchId, selectedSeats]
);
if (seats.length !== selectedSeats.length) {
throw new Error('Some selected seats are not available');
}
// Create ticket
const ticketResult = await query(
`INSERT INTO tickets (
matchId, name, email, phone, seats, deliveryMethod
) VALUES (?, ?, ?, ?, ?, ?)`,
[matchId, name, email, phone, selectedSeats.length, deliveryMethod]
);
const ticketId = ticketResult.insertId;
// Update seats status
await query(
'UPDATE seats SET status = "booked", ticketId = ? WHERE matchId = ? AND seatNumber IN (?)',
[ticketId, matchId, selectedSeats]
);
// Update match available seats
await query(
'UPDATE matches SET availableSeats = availableSeats - ? WHERE id = ?',
[selectedSeats.length, matchId]
);
// Generate PDF
const pdfFileName = `${Date.now()}-${name}-${selectedSeats.length}.pdf`;
const pdfPath = path.join(__dirname, '..', '..', 'public', 'uploads', pdfFileName);
const match = await query('SELECT * FROM matches WHERE id = ?', [matchId]);
await generateTicketPDF({
ticketId,
match: match[0],
name,
email,
phone,
seats: seats,
pdfFile: pdfFileName
});
// Update ticket with PDF path
await query(
'UPDATE tickets SET pdfFile = ? WHERE id = ?',
[`/uploads/${pdfFileName}`, ticketId]
);
// Send email if requested
if (deliveryMethod === 'email') {
await sendEmail({
to: email,
subject: `Your tickets for ${match[0].name}`,
text: `Thank you for booking tickets for ${match[0].name}. Your seat numbers are: ${selectedSeats.join(', ')}`,
attachments: [{
filename: pdfFileName,
path: pdfPath
}]
});
}
// Commit transaction
await query('COMMIT');
res.status(201).json({
message: 'Ticket created successfully',
ticketId,
pdfUrl: `/uploads/${pdfFileName}`
});
} catch (error) {
// Rollback transaction on error
await query('ROLLBACK');
throw error;
}
} catch (error) {
console.error('Error creating ticket:', error);
res.status(500).json({
message: 'Failed to create ticket',
error: error.message
});
}
};
export const getMatchSeats = async (req, res) => {
try {
const { matchId } = req.params;
const seats = await query(`
SELECT s.*, t.name as bookedBy, t.email as bookedByEmail
FROM seats s
LEFT JOIN tickets t ON s.ticketId = t.id
WHERE s.matchId = ?
ORDER BY s.seatNumber
`, [matchId]);
res.status(200).json(seats);
} catch (error) {
console.error('Error fetching seats:', error);
res.status(500).json({
message: 'Failed to fetch seats',
error: error.message
});
}
};
export const getTicketStatus = async (req, res) => {
try {
const ticketId = req.params.ticketId || req;
// If called as a controller (req, res), req.params.ticketId is used
// If called as a service (just ticketId), req is the id
const id = typeof ticketId === 'object' ? ticketId.ticketId : ticketId;
const result = await query('SELECT * FROM tickets WHERE id = ?', [id]);
if (!result || result.length === 0) {
if (res) {
return res.status(404).json({ message: 'Ticket not found' });
} else {
return null;
}
}
if (res) {
res.json(result[0]);
} else {
return result[0];
}
} catch (error) {
console.error('Error getting ticket status:', error);
if (res) {
res.status(500).json({ message: 'Failed to get ticket status', error: error.message });
} else {
throw error;
}
}
};