From 3ce9d1d1801c4b09d98da40eb755607f1945f1a4 Mon Sep 17 00:00:00 2001 From: Mayank Mishra Date: Fri, 27 Mar 2026 11:57:05 +0530 Subject: [PATCH] sending the food trainer pick up and navigation details in the get user itinerary api --- .../user/services/itinerary.service.ts | 270 +++++++++++++++--- 1 file changed, 232 insertions(+), 38 deletions(-) diff --git a/src/modules/user/services/itinerary.service.ts b/src/modules/user/services/itinerary.service.ts index 4386fd8..2a19057 100644 --- a/src/modules/user/services/itinerary.service.ts +++ b/src/modules/user/services/itinerary.service.ts @@ -232,7 +232,7 @@ const getUniqueDatesForScheduleDetail = ( @Injectable() export class ItineraryService { - constructor(private prisma: PrismaClient) {} + constructor(private prisma: PrismaClient) { } async getUserItineraryDetails(userXid: number) { const [userLocation, activityEntries, travellerType, energyLevel] = await Promise.all([ @@ -398,15 +398,15 @@ export class ItineraryService { ), energyLevel: entry.Activities?.activityType?.energyLevel ? { - id: entry.Activities.activityType.energyLevel.id, - energyLevelName: - entry.Activities.activityType.energyLevel.energyLevelName, - energyIcon: - entry.Activities.activityType.energyLevel.energyIcon, - energyIconPresignedUrl: await attachPresignedUrl( - entry.Activities.activityType.energyLevel.energyIcon, - ), - } + id: entry.Activities.activityType.energyLevel.id, + energyLevelName: + entry.Activities.activityType.energyLevel.energyLevelName, + energyIcon: + entry.Activities.activityType.energyLevel.energyIcon, + energyIconPresignedUrl: await attachPresignedUrl( + entry.Activities.activityType.energyLevel.energyIcon, + ), + } : null, media: await attachMediaWithPresignedUrl( entry.Activities?.ActivitiesMedia ?? [], @@ -640,9 +640,9 @@ export class ItineraryService { const slotEnd = scheduleHeader.activity.activityDurationMins ? addMinutes( - slotStart, - scheduleHeader.activity.activityDurationMins, - ) + slotStart, + scheduleHeader.activity.activityDurationMins, + ) : combineDateAndTime(slotDate, slot.endTime); if (!slotEnd) { @@ -665,7 +665,7 @@ export class ItineraryService { if ( activityItem.occurenceDate && formatDateKey(slotDate) !== - formatDateKey(parseDateValue(activityItem.occurenceDate)) + formatDateKey(parseDateValue(activityItem.occurenceDate)) ) { return null; } @@ -879,6 +879,97 @@ export class ItineraryService { checkInAddress: true, checkInLat: true, checkInLong: true, + foodAvailable: true, + foodIsChargeable: true, + trainerAvailable: true, + trainerIsChargeable: true, + inActivityAvailable: true, + inActivityIsChargeable: true, + pickUpDropAvailable: true, + pickUpDropIsChargeable: true, + activityFoodTypes: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + foodTypeXid: true, + foodType: { + select: { + id: true, + foodTypeName: true, + }, + }, + }, + }, + ActivityFoodCost: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + baseAmount: true, + totalAmount: true, + }, + }, + ActivityTrainers: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + baseAmount: true, + totalAmount: true, + }, + }, + ActivityNavigationModes: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + navigationModeName: true, + isInActivityChargeable: true, + navigationModesBasePrice: true, + navigationModesTotalPrice: true, + }, + }, + ActivityPickUpDetails: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + isPickUp: true, + locationLat: true, + locationLong: true, + locationAddress: true, + transportBasePrice: true, + transportTotalPrice: true, + }, + }, + activityPickUpTransports: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + transportModeXid: true, + transportMode: { + select: { + id: true, + transportModeName: true, + transportModeIcon: true, + }, + }, + }, + }, ActivitiesMedia: { where: { isActive: true, @@ -921,9 +1012,8 @@ export class ItineraryService { const formattedItineraries = await Promise.all( itineraries.map(async (itinerary) => { - const ownerFullName = `${itinerary.owner.firstName ?? ''} ${ - itinerary.owner.lastName ?? '' - }`.trim(); + const ownerFullName = `${itinerary.owner.firstName ?? ''} ${itinerary.owner.lastName ?? '' + }`.trim(); const members = await Promise.all( itinerary.ItineraryMembers.map(async (member) => ({ @@ -932,9 +1022,8 @@ export class ItineraryService { memberRole: member.memberRole, memberStatus: member.memberStatus, invitedByXid: member.invitedByXid, - fullName: `${member.member.firstName ?? ''} ${ - member.member.lastName ?? '' - }`.trim(), + fullName: `${member.member.firstName ?? ''} ${member.member.lastName ?? '' + }`.trim(), firstName: member.member.firstName, lastName: member.member.lastName, profileImage: member.member.profileImage, @@ -985,6 +1074,80 @@ export class ItineraryService { media: await attachMediaWithPresignedUrl( item.activity.ActivitiesMedia, ), + foodDetails: { + foodAvailable: item.activity.foodAvailable, + foodIsChargeable: item.activity.foodIsChargeable, + foodTypes: item.activity.activityFoodTypes.map((foodType) => ({ + id: foodType.id, + foodTypeXid: foodType.foodTypeXid, + foodType: foodType.foodType, + })), + foodCost: item.activity.ActivityFoodCost.map((foodCost) => ({ + id: foodCost.id, + baseAmount: foodCost.baseAmount, + totalAmount: foodCost.totalAmount, + })), + }, + trainerDetails: { + trainerAvailable: item.activity.trainerAvailable, + trainerIsChargeable: item.activity.trainerIsChargeable, + trainerCost: item.activity.ActivityTrainers.map((trainer) => ({ + id: trainer.id, + baseAmount: trainer.baseAmount, + totalAmount: trainer.totalAmount, + })), + }, + navigationDetails: { + inActivityAvailable: item.activity.inActivityAvailable, + inActivityIsChargeable: item.activity.inActivityIsChargeable, + navigationModes: item.activity.ActivityNavigationModes.map( + (navigationMode) => ({ + id: navigationMode.id, + navigationModeName: navigationMode.navigationModeName, + isInActivityChargeable: + navigationMode.isInActivityChargeable, + navigationModesBasePrice: + navigationMode.navigationModesBasePrice, + navigationModesTotalPrice: + navigationMode.navigationModesTotalPrice, + }), + ), + }, + pickUpDetails: { + pickUpDropAvailable: item.activity.pickUpDropAvailable, + pickUpDropIsChargeable: + item.activity.pickUpDropIsChargeable, + details: item.activity.ActivityPickUpDetails.map( + (pickUpDetail) => ({ + id: pickUpDetail.id, + isPickUp: pickUpDetail.isPickUp, + locationLat: pickUpDetail.locationLat, + locationLong: pickUpDetail.locationLong, + locationAddress: pickUpDetail.locationAddress, + transportBasePrice: pickUpDetail.transportBasePrice, + transportTotalPrice: pickUpDetail.transportTotalPrice, + }), + ), + transportModes: await Promise.all( + item.activity.activityPickUpTransports.map( + async (transport) => ({ + id: transport.id, + transportModeXid: transport.transportModeXid, + transportMode: { + id: transport.transportMode.id, + transportModeName: + transport.transportMode.transportModeName, + transportModeIcon: + transport.transportMode.transportModeIcon, + transportModeIconPresignedUrl: + await attachPresignedUrl( + transport.transportMode.transportModeIcon, + ), + }, + }), + ), + ), + }, }, venue: item.venue, scheduleHeader: item.scheduledHeader, @@ -1150,6 +1313,7 @@ export class ItineraryService { id: true, activityTitle: true, activityDurationMins: true, + activityDescription: true, checkInLat: true, checkInLong: true, checkInAddress: true, @@ -1246,6 +1410,17 @@ export class ItineraryService { venueName: true, venueLabel: true, venueCapacity: true, + ActivityVenueArtifacts: { + where: { + isActive: true, + deletedAt: null, + }, + select: { + id: true, + mediaType: true, + mediaFileName: true, + }, + }, availableSeats: true, ScheduleHeader: { where: { @@ -1411,6 +1586,8 @@ export class ItineraryService { venueXid: venue.id, venueName: venue.venueName, venueLabel: venue.venueLabel, + mediaFileName: venue.ActivityVenueArtifacts[0]?.mediaFileName ?? null, + mediaType: venue.ActivityVenueArtifacts[0]?.mediaType ?? null, venueCapacity: venue.venueCapacity, availableSeats: venue.availableSeats, slotDate: formatDateKey(slotDate), @@ -1430,11 +1607,27 @@ export class ItineraryService { }), ); - if (!availableSlots.length) { + const sanitizedAvailableSlots = availableSlots.filter( + ( + slot, + ): slot is NonNullable<(typeof availableSlots)[number]> => + Boolean(slot), + ); + + const availableSlotsWithPresignedUrl = await Promise.all( + sanitizedAvailableSlots.map(async (slot) => ({ + ...slot, + mediaFileNamePresignedUrl: await attachPresignedUrl( + slot.mediaFileName, + ), + })), + ); + + if (!availableSlotsWithPresignedUrl.length) { return null; } - availableSlots.sort( + availableSlotsWithPresignedUrl.sort( (first, second) => new Date(first!.startDateTime).getTime() - new Date(second!.startDateTime).getTime(), @@ -1454,29 +1647,30 @@ export class ItineraryService { bucketTypeName: entry.bucketTypeName, distance, activityTitle: activity.activityTitle, + activityDescription: activity.activityDescription, activityDurationMins, activityCoverImage: coverImage?.mediaFileName ?? null, activityCoverImagePresignedUrl: await attachPresignedUrl( coverImage?.mediaFileName, ), - venue: availableSlots[0] + venue: availableSlotsWithPresignedUrl[0] ? { - venueXid: availableSlots[0].venueXid, - venueName: availableSlots[0].venueName, - venueLabel: availableSlots[0].venueLabel, - } + venueXid: availableSlotsWithPresignedUrl[0].venueXid, + venueName: availableSlotsWithPresignedUrl[0].venueName, + venueLabel: availableSlotsWithPresignedUrl[0].venueLabel, + } : null, - availableSlots, + availableSlots: availableSlotsWithPresignedUrl, entryType: activity.ActivityAllowedEntry[0]?.allowedEntryType ?? null, energyLevel: energyLevel ? { - energyLevelXid: energyLevel.id, - energyLevelName: energyLevel.energyLevelName, - energyLevelIcon: energyLevel.energyIcon, - energyLevelIconPresignedUrl: await attachPresignedUrl( - energyLevel.energyIcon, - ), - } + energyLevelXid: energyLevel.id, + energyLevelName: energyLevel.energyLevelName, + energyLevelIcon: energyLevel.energyIcon, + energyLevelIconPresignedUrl: await attachPresignedUrl( + energyLevel.energyIcon, + ), + } : null, checkInAddress: activity.checkInAddress, checkInCity: activity.checkInCity, @@ -1486,9 +1680,9 @@ export class ItineraryService { checkInLong: activity.checkInLong, interest: activity.activityType?.interests ? { - id: activity.activityType.interests.id, - interestName: activity.activityType.interests.interestName, - } + id: activity.activityType.interests.id, + interestName: activity.activityType.interests.interestName, + } : null, }; }),