MIF_E31220277/denta-api/app/api/appointments/[id]/route.ts

315 lines
8.3 KiB
TypeScript

import db from "@/lib/db";
import { getFieldById } from "@/utils/common";
import { NextResponse } from "next/server";
export async function PATCH(
req: Request,
props: { params: Promise<{ id: string }> }
) {
const params = await props.params;
const { searchParams } = new URL(req.url);
const id = searchParams.get('id') || params.id;
const body = await req.json();
const { status, scheduleId, pasienId, koasId, timeslotId } = body;
console.log('Updating appointment with data:', body);
console.log('Appointment ID:', id);
try {
// First, check if the appointment exists
const existingAppointment = await db.appointment.findUnique({
where: { id },
});
if (!existingAppointment) {
console.error(`Appointment with ID ${id} not found in the database`);
return NextResponse.json(
{ error: 'Appointment not found' },
{ status: 404 }
);
}
console.log('Found existing appointment:', existingAppointment);
// Use the data from the existing appointment if not provided in the body
const effectiveScheduleId = scheduleId || existingAppointment.scheduleId;
const effectivePasienId = pasienId || existingAppointment.pasienId;
const effectiveKoasId = koasId || existingAppointment.koasId;
const effectiveTimeslotId = timeslotId || existingAppointment.timeslotId;
console.log('Using effective IDs:', {
scheduleId: effectiveScheduleId,
pasienId: effectivePasienId,
koasId: effectiveKoasId,
timeslotId: effectiveTimeslotId,
});
// Update the appointment status directly without additional checks to simplify
const appointment = await db.appointment.update({
where: { id },
data: { status },
include: {
schedule: {
include: {
post: true,
timeslot: {
where: { id: effectiveTimeslotId },
},
},
},
},
});
console.log('Updated appointment successfully with status:', status);
// Handle timeslot participant count updates based on status change
if (status === 'Canceled' || status === 'Rejected') {
// If canceling, decrease participant count
if (existingAppointment.status === 'Confirmed') {
// Only decrement if it was previously confirmed
const timeslot = await db.timeslot.findUnique({
where: { id: effectiveTimeslotId },
});
if (timeslot) {
console.log('Updating timeslot participant count for cancellation');
await db.timeslot.update({
where: { id: effectiveTimeslotId },
data: {
currentParticipants: Math.max(
0,
timeslot.currentParticipants - 1
),
isAvailable: true,
},
});
}
}
} else if (
status === 'Confirmed' &&
existingAppointment.status !== 'Confirmed'
) {
// If confirming a previously unconfirmed appointment
const timeslot = await db.timeslot.findUnique({
where: { id: effectiveTimeslotId },
});
if (timeslot) {
if (!timeslot.isAvailable) {
console.error(
'Cannot confirm appointment: timeslot is not available'
);
// Rollback the status change
await db.appointment.update({
where: { id },
data: { status: existingAppointment.status },
});
return NextResponse.json(
{ error: 'Timeslot is fully booked or unavailable.' },
{ status: 400 }
);
}
console.log('Updating timeslot participant count for confirmation');
const updatedTimeslot = await db.timeslot.update({
where: { id: effectiveTimeslotId },
data: {
currentParticipants: timeslot.currentParticipants + 1,
},
});
if (
updatedTimeslot.maxParticipants !== null &&
updatedTimeslot.currentParticipants >= updatedTimeslot.maxParticipants
) {
await db.timeslot.update({
where: { id: effectiveTimeslotId },
data: { isAvailable: false },
});
}
}
}
// Check if post requirements are met and update post status accordingly
const schedule = await db.schedule.findUnique({
where: { id: effectiveScheduleId },
include: { post: true },
});
if (schedule && schedule.post) {
const totalParticipants = await db.appointment.count({
where: {
scheduleId: effectiveScheduleId,
status: 'Confirmed',
},
});
console.log(
'Total confirmed participants:',
totalParticipants,
'Required:',
schedule.post.requiredParticipant
);
if (totalParticipants >= schedule.post.requiredParticipant) {
await db.post.update({
where: { id: schedule.post.id },
data: { status: 'Closed' },
});
// Reject all pending appointments
await db.appointment.updateMany({
where: {
scheduleId: effectiveScheduleId,
status: 'Pending',
},
data: { status: 'Rejected' },
});
} else {
await db.post.update({
where: { id: schedule.post.id },
data: { status: 'Open' },
});
}
}
return NextResponse.json(
{
status: 'Success',
message: 'Appointment updated successfully',
data: { appointment },
},
{ status: 200 }
);
} catch (error) {
console.error('Error updating appointment:', error);
return NextResponse.json(
{ error: 'Internal Server Error', details: (error as Error).message },
{ status: 500 }
);
}
}
export async function PUT(
req: Request,
props: { params: Promise<{ id: string }> }
) {
const params = await props.params;
const { searchParams } = new URL(req.url);
const id = searchParams.get('id') || params.id;
const body = await req.json();
const { scheduleId, pasienId, koasId, timeslotId, status, date } = body;
try {
} catch (error) {
console.error('Error updating appointment', error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}
export async function DELETE(
req: Request,
props: { params: Promise<{ id: string }> }
) {
const params = await props.params;
const { searchParams } = new URL(req.url);
const id = searchParams.get('id') || params.id;
try {
if (!id) {
return NextResponse.json(
{ error: 'Appoid is required' },
{ status: 400 }
);
}
await db.appointment.delete({
where: { id: id },
});
return NextResponse.json(
{ message: 'Appointment deleted successfully' },
{ status: 200 }
);
} catch (error) {
console.error('Error deleting appointment', error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}
export async function GET(
req: Request,
props: { params: Promise<{ id: string }> }
) {
const params = await props.params;
const { searchParams } = new URL(req.url);
const id = searchParams.get('id') || params.id;
try {
if (!id) {
return NextResponse.json(
{ error: 'Appointment ID is required' },
{ status: 400 }
);
}
const appointment = await db.appointment.findUnique({
where: { id },
include: {
pasien: {
include: {
user: true,
},
},
koas: {
include: {
user: true,
},
},
schedule: {
include: {
post: {
include: {
treatment: true,
Review: true,
},
},
timeslot: true,
},
},
},
});
if (!appointment) {
return NextResponse.json(
{ error: 'Appointment not found' },
{ status: 404 }
);
}
return NextResponse.json(
{
status: 'Success',
message: 'Appointment retrieved successfully',
data: appointment,
},
{ status: 200 }
);
} catch (error) {
console.error('Error retrieving appointment', error);
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
);
}
}