146 lines
4.7 KiB
TypeScript
146 lines
4.7 KiB
TypeScript
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
|
import { prismaClient } from '../../../../common/database/prisma.lambda.service';
|
|
import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser';
|
|
import { safeHandler } from '../../../../common/utils/handlers/safeHandler';
|
|
import ApiError from '../../../../common/utils/helper/ApiError';
|
|
import { ItineraryService } from '../../services/itinerary.service';
|
|
|
|
const itineraryService = new ItineraryService(prismaClient);
|
|
|
|
export const handler = safeHandler(async (
|
|
event: APIGatewayProxyEvent,
|
|
context?: Context,
|
|
): Promise<APIGatewayProxyResult> => {
|
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
|
if (!token) {
|
|
throw new ApiError(
|
|
400,
|
|
'This is a protected route. Please provide a valid token.',
|
|
);
|
|
}
|
|
|
|
const userInfo = await verifyUserToken(token);
|
|
const userId = Number(userInfo.id);
|
|
|
|
if (!userId || Number.isNaN(userId)) {
|
|
throw new ApiError(400, 'Invalid user ID');
|
|
}
|
|
|
|
let body: Record<string, any> = {};
|
|
if (event.body) {
|
|
try {
|
|
body = JSON.parse(event.body);
|
|
} catch {
|
|
throw new ApiError(400, 'Invalid JSON body');
|
|
}
|
|
}
|
|
|
|
const activities = Array.isArray(body.activities) ? body.activities : [];
|
|
|
|
if (!body.startDate || !body.endDate || !body.startTime || !body.endTime) {
|
|
throw new ApiError(
|
|
400,
|
|
'startDate, endDate, startTime and endTime are required.',
|
|
);
|
|
}
|
|
|
|
if (!activities.length) {
|
|
throw new ApiError(400, 'At least one activity is required.');
|
|
}
|
|
|
|
for (const activity of activities) {
|
|
if (
|
|
!activity.activityXid ||
|
|
!activity.venueXid ||
|
|
!activity.scheduleHeaderXid ||
|
|
!activity.modeOfTravel ||
|
|
activity.travelTimeBetweenPointsMins === undefined ||
|
|
activity.travelTimeBetweenPointsMins === null
|
|
) {
|
|
throw new ApiError(
|
|
400,
|
|
'Each activity must include activityXid, venueXid, scheduleHeaderXid, modeOfTravel and travelTimeBetweenPointsMins.',
|
|
);
|
|
}
|
|
}
|
|
|
|
const payload = {
|
|
title: body.title,
|
|
startDate: body.startDate,
|
|
endDate: body.endDate,
|
|
startTime: body.startTime,
|
|
endTime: body.endTime,
|
|
activities: activities.map((activity: any) => ({
|
|
activityXid: Number(activity.activityXid),
|
|
venueXid: Number(activity.venueXid),
|
|
scheduleHeaderXid: Number(activity.scheduleHeaderXid),
|
|
modeOfTravel: activity.modeOfTravel,
|
|
travelTimeBetweenPointsMins: Number(
|
|
activity.travelTimeBetweenPointsMins,
|
|
),
|
|
kmForNextPoint:
|
|
activity.kmForNextPoint !== undefined &&
|
|
activity.kmForNextPoint !== null
|
|
? Number(activity.kmForNextPoint)
|
|
: undefined,
|
|
occurenceDate: activity.occurenceDate,
|
|
selectedStartTime: activity.selectedStartTime,
|
|
selectedEndTime: activity.selectedEndTime,
|
|
itineraryType: activity.itineraryType,
|
|
paxCount:
|
|
activity.paxCount !== undefined && activity.paxCount !== null
|
|
? Number(activity.paxCount)
|
|
: undefined,
|
|
totalAmount:
|
|
activity.totalAmount !== undefined && activity.totalAmount !== null
|
|
? Number(activity.totalAmount)
|
|
: undefined,
|
|
locationLat:
|
|
activity.locationLat !== undefined && activity.locationLat !== null
|
|
? Number(activity.locationLat)
|
|
: undefined,
|
|
locationLong:
|
|
activity.locationLong !== undefined && activity.locationLong !== null
|
|
? Number(activity.locationLong)
|
|
: undefined,
|
|
locationAddress: activity.locationAddress,
|
|
})),
|
|
};
|
|
|
|
if (
|
|
payload.activities.some(
|
|
(activity) =>
|
|
Number.isNaN(activity.activityXid) ||
|
|
Number.isNaN(activity.venueXid) ||
|
|
Number.isNaN(activity.scheduleHeaderXid) ||
|
|
Number.isNaN(activity.travelTimeBetweenPointsMins) ||
|
|
(activity.kmForNextPoint !== undefined &&
|
|
Number.isNaN(activity.kmForNextPoint)) ||
|
|
(activity.paxCount !== undefined && Number.isNaN(activity.paxCount)) ||
|
|
(activity.totalAmount !== undefined &&
|
|
Number.isNaN(activity.totalAmount)) ||
|
|
(activity.locationLat !== undefined &&
|
|
Number.isNaN(activity.locationLat)) ||
|
|
(activity.locationLong !== undefined &&
|
|
Number.isNaN(activity.locationLong)),
|
|
)
|
|
) {
|
|
throw new ApiError(400, 'One or more numeric itinerary values are invalid.');
|
|
}
|
|
|
|
const result = await itineraryService.saveUserItinerary(userId, payload);
|
|
|
|
return {
|
|
statusCode: 201,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Access-Control-Allow-Origin': '*',
|
|
},
|
|
body: JSON.stringify({
|
|
success: true,
|
|
message: 'Itinerary saved successfully',
|
|
data: result,
|
|
}),
|
|
};
|
|
});
|