diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c8bfc82..c8191e6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -855,41 +855,41 @@ model HostTrack { // ACTIVITY MODELS model Activities { - id Int @id @default(autoincrement()) - hostXid Int @map("host_xid") - host HostHeader @relation(fields: [hostXid], references: [id], onDelete: Cascade) - activityTypeXid Int @map("activity_type_xid") - activityType ActivityTypes @relation(fields: [activityTypeXid], references: [id], onDelete: Restrict) - frequenciesXid Int? @map("frequencies_xid") - frequency Frequencies? @relation(fields: [frequenciesXid], references: [id], onDelete: Restrict) - activityRefNumber String? @map("activity_ref_number") @db.VarChar(30) - activityTitle String? @map("activity_title") @db.VarChar(150) - activityDescription String? @map("activity_description") @db.VarChar(2000) - checkInLat Float? @map("check_in_lat") - checkInLong Float? @map("check_in_long") - checkInAddress String? @map("check_in_address") @db.VarChar(150) - isCheckOutSame Boolean? @default(true) @map("is_check_out_same") - checkOutLat Float? @map("check_out_lat") - checkOutLong Float? @map("check_out_long") - checkOutAddress String? @map("check_out_address") @db.VarChar(150) - set_early_checkin_time_mins String @default("null") @map("set_early_checkin_time_mins") @db.VarChar(200) - activityDurationMins Int? @map("activity_duration_mins") - foodAvailable Boolean? @map("food_available") - foodIsChargeable Boolean? @map("food_is_chargeable") - alcoholAvailable Boolean? @map("alcohol_available") - trainerAvailable Boolean? @map("trainer_available") - trainerIsChargeable Boolean? @map("trainer_is_chargeable") - pickUpDropAvailable Boolean? @map("pick_up_drop_available") - pickUpDropIsChargeable Boolean? @map("pick_up_drop_is_chargeable") - inActivityAvailable Boolean? @map("in_activity_available") - inActivityIsChargeable Boolean? @map("in_activity_is_chargeable") - is_late_checking_allowed Boolean? @map("is_late_checking_allowed") - equipmentAvailable Boolean? @map("equipment_available") - equipmentIsChargeable Boolean? @map("equipment_is_chargeable") - cancellationAvailable Boolean? @map("cancellation_available") + id Int @id @default(autoincrement()) + hostXid Int @map("host_xid") + host HostHeader @relation(fields: [hostXid], references: [id], onDelete: Cascade) + activityTypeXid Int @map("activity_type_xid") + activityType ActivityTypes @relation(fields: [activityTypeXid], references: [id], onDelete: Restrict) + frequenciesXid Int? @map("frequencies_xid") + frequency Frequencies? @relation(fields: [frequenciesXid], references: [id], onDelete: Restrict) + activityRefNumber String? @map("activity_ref_number") @db.VarChar(30) + activityTitle String? @map("activity_title") @db.VarChar(150) + activityDescription String? @map("activity_description") @db.VarChar(2000) + checkInLat Float? @map("check_in_lat") + checkInLong Float? @map("check_in_long") + checkInAddress String? @map("check_in_address") @db.VarChar(150) + isCheckOutSame Boolean? @default(true) @map("is_check_out_same") + checkOutLat Float? @map("check_out_lat") + checkOutLong Float? @map("check_out_long") + checkOutAddress String? @map("check_out_address") @db.VarChar(150) + set_early_checkin_time_mins String @default("null") @map("set_early_checkin_time_mins") @db.VarChar(200) + activityDurationMins Int? @map("activity_duration_mins") + foodAvailable Boolean? @map("food_available") + foodIsChargeable Boolean? @map("food_is_chargeable") + alcoholAvailable Boolean? @map("alcohol_available") + trainerAvailable Boolean? @map("trainer_available") + trainerIsChargeable Boolean? @map("trainer_is_chargeable") + pickUpDropAvailable Boolean? @map("pick_up_drop_available") + pickUpDropIsChargeable Boolean? @map("pick_up_drop_is_chargeable") + inActivityAvailable Boolean? @map("in_activity_available") + inActivityIsChargeable Boolean? @map("in_activity_is_chargeable") + is_late_checking_allowed Boolean? @map("is_late_checking_allowed") + equipmentAvailable Boolean? @map("equipment_available") + equipmentIsChargeable Boolean? @map("equipment_is_chargeable") + cancellationAvailable Boolean? @map("cancellation_available") // 🔹 Creator / owner - userId Int? - user User? @relation("UserActivities", fields: [userId], references: [id]) + userId Int? + user User? @relation("UserActivities", fields: [userId], references: [id]) // 🔹 Account Manager accountManagerXid Int? @@ -991,10 +991,10 @@ model ActivityVenues { id Int @id @default(autoincrement()) activityXid Int @map("activity_xid") activity Activities @relation(fields: [activityXid], references: [id], onDelete: Cascade) - venueName String @map("venue_name") @db.VarChar(50) - venueLabel String @default("null") @map("venue_label") @db.VarChar(70) - venueCapacity Int @map("venue_capacity") - availableSeats Int @map("available_seats") + venueName String? @map("venue_name") @db.VarChar(50) + venueLabel String? @map("venue_label") @db.VarChar(70) + venueCapacity Int? @map("venue_capacity") + availableSeats Int? @map("available_seats") isMinPeopleReqMandatory Boolean @default(false) @map("is_min_people_req_mandatory") minPeopleRequired Int? @map("min_people_required") minReqfullfilledBeforeMins Int? @map("min_req_fullfilled_before_mins") diff --git a/src/modules/host/services/host.service.ts b/src/modules/host/services/host.service.ts index 654749d..d796dc8 100644 --- a/src/modules/host/services/host.service.ts +++ b/src/modules/host/services/host.service.ts @@ -106,7 +106,7 @@ const bucket = config.aws.bucketName; @Injectable() export class HostService { - constructor(private prisma: PrismaClient) {} + constructor(private prisma: PrismaClient) { } async createHost(data: CreateHostDto) { return this.prisma.user.create({ data }); @@ -115,8 +115,8 @@ export class HostService { async getAllHosts() { return this.prisma.user.findMany({ where: { roleXid: 3 } }); } - - + + async getActivityDetailsById(activityXid: number) { return this.prisma.activities.findFirst({ where: { id: activityXid } }); } @@ -774,7 +774,7 @@ export class HostService { if ( existingHostCompany && existingHostCompany.hostStatusInternal === - HOST_STATUS_INTERNAL.HOST_TO_UPDATE && + HOST_STATUS_INTERNAL.HOST_TO_UPDATE && !isDraft ) { hostStatusInternal = HOST_STATUS_INTERNAL.HOST_SUBMITTED; @@ -787,7 +787,7 @@ export class HostService { else if ( existingHostCompany && existingHostCompany.hostStatusInternal === - HOST_STATUS_INTERNAL.HOST_TO_UPDATE && + HOST_STATUS_INTERNAL.HOST_TO_UPDATE && isDraft ) { // keep original @@ -898,19 +898,19 @@ export class HostService { // Safely handle city connection - only connect if valid ID exists cities: parentCompanyData?.cityXid && - !isNaN(Number(parentCompanyData.cityXid)) + !isNaN(Number(parentCompanyData.cityXid)) ? { connect: { id: Number(parentCompanyData.cityXid) } } : undefined, states: parentCompanyData?.stateXid && - !isNaN(Number(parentCompanyData.stateXid)) + !isNaN(Number(parentCompanyData.stateXid)) ? { connect: { id: Number(parentCompanyData.stateXid) } } : undefined, countries: parentCompanyData?.countryXid && - !isNaN(Number(parentCompanyData.countryXid)) + !isNaN(Number(parentCompanyData.countryXid)) ? { connect: { id: Number(parentCompanyData.countryXid) } } : undefined, pinCode: parentCompanyData.pinCode || null, @@ -1043,53 +1043,53 @@ export class HostService { // } // } // documents handling (FINAL FIX) -if (documents?.length) { - for (const doc of documents) { - if (!doc.filePath) continue; + if (documents?.length) { + for (const doc of documents) { + if (!doc.filePath) continue; - // 🔹 CUSTOM DOCUMENTS → ALWAYS CREATE - if (doc.documentTypeXid === 9) { - await tx.hostDocuments.create({ - data: { - hostXid: updatedHost.id, - documentTypeXid: doc.documentTypeXid, - documentName: sanitizeDocumentName(doc.documentName), - filePath: doc.filePath, - }, - }); - continue; - } + // 🔹 CUSTOM DOCUMENTS → ALWAYS CREATE + if (doc.documentTypeXid === 9) { + await tx.hostDocuments.create({ + data: { + hostXid: updatedHost.id, + documentTypeXid: doc.documentTypeXid, + documentName: sanitizeDocumentName(doc.documentName), + filePath: doc.filePath, + }, + }); + continue; + } - // 🔹 NORMAL DOCUMENTS → UPSERT (ONE PER TYPE) - const existingDoc = await tx.hostDocuments.findFirst({ - where: { - hostXid: updatedHost.id, - documentTypeXid: doc.documentTypeXid, - }, - }); + // 🔹 NORMAL DOCUMENTS → UPSERT (ONE PER TYPE) + const existingDoc = await tx.hostDocuments.findFirst({ + where: { + hostXid: updatedHost.id, + documentTypeXid: doc.documentTypeXid, + }, + }); - if (existingDoc) { - await tx.hostDocuments.update({ - where: { id: existingDoc.id }, - data: { - filePath: doc.filePath, - documentName: - sanitizeDocumentName(doc.documentName) || - existingDoc.documentName, - }, - }); - } else { - await tx.hostDocuments.create({ - data: { - hostXid: updatedHost.id, - documentTypeXid: doc.documentTypeXid, - documentName: sanitizeDocumentName(doc.documentName), - filePath: doc.filePath, - }, - }); - } - } -} + if (existingDoc) { + await tx.hostDocuments.update({ + where: { id: existingDoc.id }, + data: { + filePath: doc.filePath, + documentName: + sanitizeDocumentName(doc.documentName) || + existingDoc.documentName, + }, + }); + } else { + await tx.hostDocuments.create({ + data: { + hostXid: updatedHost.id, + documentTypeXid: doc.documentTypeXid, + documentName: sanitizeDocumentName(doc.documentName), + filePath: doc.filePath, + }, + }); + } + } + } // parent logic untouched @@ -1109,19 +1109,19 @@ if (documents?.length) { address2: parentCompanyData.address2 || null, cities: parentCompanyData?.cityXid && - !isNaN(Number(parentCompanyData.cityXid)) + !isNaN(Number(parentCompanyData.cityXid)) ? { connect: { id: Number(parentCompanyData.cityXid) } } : undefined, states: parentCompanyData?.stateXid && - !isNaN(Number(parentCompanyData.stateXid)) + !isNaN(Number(parentCompanyData.stateXid)) ? { connect: { id: Number(parentCompanyData.stateXid) } } : undefined, countries: parentCompanyData?.countryXid && - !isNaN(Number(parentCompanyData.countryXid)) + !isNaN(Number(parentCompanyData.countryXid)) ? { connect: { id: Number(parentCompanyData.countryXid) } } : undefined, pinCode: parentCompanyData.pinCode || null, @@ -1167,19 +1167,19 @@ if (documents?.length) { address2: parentCompanyData.address2 || null, cities: parentCompanyData?.cityXid && - !isNaN(Number(parentCompanyData.cityXid)) + !isNaN(Number(parentCompanyData.cityXid)) ? { connect: { id: Number(parentCompanyData.cityXid) } } : undefined, states: parentCompanyData?.stateXid && - !isNaN(Number(parentCompanyData.stateXid)) + !isNaN(Number(parentCompanyData.stateXid)) ? { connect: { id: Number(parentCompanyData.stateXid) } } : undefined, countries: parentCompanyData?.countryXid && - !isNaN(Number(parentCompanyData.countryXid)) + !isNaN(Number(parentCompanyData.countryXid)) ? { connect: { id: Number(parentCompanyData.countryXid) } } : undefined, pinCode: parentCompanyData.pinCode || null, @@ -2477,6 +2477,18 @@ if (documents?.length) { throw new ApiError(400, 'activityXid is required'); } + payload.venues = Array.isArray(payload.venues) + ? payload.venues + .filter(v => v && typeof v === 'object') + .map(v => ({ + ...v, + venueName: v.venueName ?? null, + venueLabel: v.venueLabel ?? null, + prices: Array.isArray(v.prices) ? v.prices : [], + media: Array.isArray(v.media) ? v.media : [], + })) + : []; + /* ===================================================== * HARD NORMALIZATION (SERVICE-LEVEL) * ===================================================== */ @@ -2582,9 +2594,9 @@ if (documents?.length) { const rootTaxes = taxIds.length > 0 ? await this.prisma.taxes.findMany({ - where: { id: { in: taxIds }, isActive: true }, - select: { id: true, taxPer: true }, - }) + where: { id: { in: taxIds }, isActive: true }, + select: { id: true, taxPer: true }, + }) : []; if (taxIds.length !== rootTaxes.length) { @@ -2802,8 +2814,8 @@ if (documents?.length) { const venueRow = await tx.activityVenues.create({ data: { activityXid, - venueName: venue.venueName, - venueLabel: venue.venueLabel, + venueName: venue.venueName ?? null, + venueLabel: venue.venueLabel ?? null, venueCapacity: toNumber(venue.venueCapacity) ?? 0, availableSeats: toNumber(venue.availableSeats) ?? 0, isMinPeopleReqMandatory: venue.isMinPeopleReqMandatory, @@ -3452,7 +3464,7 @@ if (documents?.length) { }, }, ActivityPQQSuggestions: { - where: { isActive: true , isReviewed :false }, + where: { isActive: true, isReviewed: false }, select: { id: true, title: true,