diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e33cac8..33218f0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -66,6 +66,7 @@ model User { friendOf Friends[] @relation("FriendUser") userAddressDetails UserAddressDetails[] userDocuments UserDocuments[] + activityTracks ActivityTrack[] @@map("users") @@schema("usr") @@ -908,6 +909,7 @@ model Activities { ActivityEquipmentTaxes ActivityEquipmentTaxes[] ScheduleHeader ScheduleHeader[] ItineraryActivities ItineraryActivities[] + activityTracks ActivityTrack[] @@map("activities") @@schema("act") @@ -932,6 +934,25 @@ model ActivityOtherDetails { @@schema("act") } +model ActivityTrack { + id Int @id @default(autoincrement()) + activityXid Int @map("activity_xid") + activity Activities @relation(fields: [activityXid], references: [id], onDelete: Cascade) + trackType String? @default("PQQ") @map("track_type") + updatedByRole String? @map("updated_by_role") + trackStatus String? @map("track_status") + updatedByXid Int? @map("updated_by_xid") + user User? @relation(fields: [updatedByXid], references: [id], onDelete: Cascade) + updatedOn DateTime? @map("updated_on") + isActive Boolean @default(true) @map("is_active") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + deletedAt DateTime? @map("deleted_at") + + @@map("activity_track") + @@schema("act") +} + model ActivitiesMedia { id Int @id @default(autoincrement()) activityXid Int @map("activity_xid") diff --git a/prisma/seed.ts b/prisma/seed.ts index e05e7a4..24fd315 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -78,35 +78,51 @@ async function main() { create: { interestName: 'Chill and Zen', displayOrder: 1 }, }); const sweatmode = await prisma.interests.upsert({ - where: { interestName: 'Sweat Mode' }, + where: { interestName: 'Sweat Mode On' }, update: {}, - create: { interestName: 'Sweat Mode', displayOrder: 2 }, + create: { interestName: 'Sweat Mode On', displayOrder: 2 }, }); - const gameon = await prisma.interests.upsert({ - where: { interestName: 'Game On' }, + const trackracer = await prisma.interests.upsert({ + where: { interestName: 'Track Racer' }, update: {}, - create: { interestName: 'Game On', displayOrder: 3 }, + create: { interestName: 'Track Racer', displayOrder: 3 }, + }); + const circuitracer = await prisma.interests.upsert({ + where: { interestName: 'Circuit Racer' }, + update: {}, + create: { interestName: 'Circuit Racer', displayOrder: 4 }, + }); + const thermalGliding = await prisma.interests.upsert({ + where: { interestName: 'Thermal Gliding' }, + update: {}, + create: { interestName: 'Thermal Gliding', displayOrder: 5 }, }); const partycentral = await prisma.interests.upsert({ where: { interestName: 'Party Central' }, update: {}, - create: { interestName: 'Party Central', displayOrder: 4 }, + create: { interestName: 'Party Central', displayOrder: 6 }, }); - const artsy = await prisma.interests.upsert({ - where: { interestName: 'Artsy' }, + const aqua = await prisma.interests.upsert({ + where: { interestName: 'Aqua' }, update: {}, - create: { interestName: 'Artsy', displayOrder: 5 }, + create: { interestName: 'Aqua', displayOrder: 7 }, }); - const foodiediaries = await prisma.interests.upsert({ - where: { interestName: 'Foodie Diaries' }, + const foodie = await prisma.interests.upsert({ + where: { interestName: 'Foodie' }, update: {}, - create: { interestName: 'Foodie Diaries', displayOrder: 6 }, + create: { interestName: 'Foodie', displayOrder: 8 }, }); await prisma.activityTypes.createMany({ data: [ - { interestXid: chillandzen.id, activityTypeName: 'Cricket' }, - { interestXid: chillandzen.id, activityTypeName: 'Football' }, + { interestXid: aqua.id, activityTypeName: 'Scuba-Diving' }, + { interestXid: sweatmode.id, activityTypeName: 'Cloudboarding' }, + { interestXid: partycentral.id, activityTypeName: 'Soaring Glider' }, + { interestXid: sweatmode.id, activityTypeName: 'Speedway Racer' }, + { interestXid: aqua.id, activityTypeName: 'Aerial Surfing' }, + { interestXid: foodie.id, activityTypeName: 'Wine Tasting' }, + { interestXid: trackracer.id, activityTypeName: 'Track Racer' }, + { interestXid: thermalGliding.id, activityTypeName: 'Thermal Gliding' }, ], skipDuplicates: true, }); diff --git a/src/modules/host/services/host.service.ts b/src/modules/host/services/host.service.ts index d8ddb85..5398def 100644 --- a/src/modules/host/services/host.service.ts +++ b/src/modules/host/services/host.service.ts @@ -38,6 +38,20 @@ interface HostDocumentInput { documentName: string; filePath: string; // S3 URL } +export async function generateActivityRefNumber(tx: any) { + const lastrecord = await tx.activities.findFirst({ + orderBy: { + id: 'desc', + }, + select: { + id: true, + }, + }); + + const nextId = lastrecord ? lastrecord.id + 1 : 1; + + return `ACT-${String(nextId).padStart(6, '0')}`;; +} @Injectable() export class HostService { @@ -330,6 +344,7 @@ export class HostService { where: { id: data.hostXid }, data: { stepper: STEPPER.BANK_DETAILS_UPDATED, + currencyXid: data.currencyXid }, }); }); @@ -1206,42 +1221,48 @@ export class HostService { activityTypeXid: number, frequenciesXid?: number, ) { - // Find host header for this user - const host = await this.prisma.hostHeader.findFirst({ - where: { userXid: userId, isActive: true }, - }); - if (!host) { - throw new ApiError(404, 'Host not found for the user'); - } - // Validate activityType exists - const activityType = await this.prisma.activityTypes.findUnique({ - where: { id: activityTypeXid }, - }); - if (!activityType) { - throw new ApiError(404, 'Activity type not found'); - } + return await this.prisma.$transaction(async (tx) => { - // Optionally validate frequency - if (frequenciesXid) { - const freq = await this.prisma.frequencies.findUnique({ - where: { id: frequenciesXid }, + // Fetch host + const host = await tx.hostHeader.findFirst({ + where: { userXid: userId, isActive: true }, }); - if (!freq) throw new ApiError(404, 'Frequency not found'); - } + if (!host) throw new ApiError(404, 'Host not found for the user'); - const created = await this.prisma.activities.create({ - data: { - hostXid: host.id, - activityTypeXid: activityTypeXid, - frequenciesXid: frequenciesXid || null, - activityInternalStatus: ACTIVITY_INTERNAL_STATUS.DRAFT_PQ, - activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.DRAFT_PQ, - amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.DRAFT_PQ, - amDisplayStatus: ACTIVITY_AM_DISPLAY_STATUS.DRAFT_PQ, - }, + // Validate activityType + const activityType = await tx.activityTypes.findUnique({ + where: { id: activityTypeXid }, + }); + if (!activityType) throw new ApiError(404, 'Activity type not found'); + + // Validate frequency + if (frequenciesXid) { + const freq = await tx.frequencies.findUnique({ + where: { id: frequenciesXid }, + }); + if (!freq) throw new ApiError(404, 'Frequency not found'); + } + + // Generate reference number + const referenceNumber = await generateActivityRefNumber(tx); + + // Create activity + const created = await tx.activities.create({ + data: { + hostXid: host.id, + activityTypeXid, + frequenciesXid: frequenciesXid || null, + activityInternalStatus: ACTIVITY_INTERNAL_STATUS.DRAFT_PQ, + activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.DRAFT_PQ, + amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.DRAFT_PQ, + amDisplayStatus: ACTIVITY_AM_DISPLAY_STATUS.DRAFT_PQ, + activityRefNumber: referenceNumber, + }, + }); + + return created; }); - - return created; } + } diff --git a/src/modules/minglaradmin/services/minglar.service.ts b/src/modules/minglaradmin/services/minglar.service.ts index 8c6e50a..bfc543b 100644 --- a/src/modules/minglaradmin/services/minglar.service.ts +++ b/src/modules/minglaradmin/services/minglar.service.ts @@ -192,6 +192,18 @@ export class MinglarService { isActive: true, userStatus: USER_STATUS.ACTIVE, }, + select: { + id: true, + firstName: true, + lastName: true, + emailAddress: true, + mobileNumber: true, + roleXid: true, + isProfileUpdated: true, + userStatus: true, + profileImage: true, + userPassword: true, + } }); if (!existingUser) { @@ -214,6 +226,16 @@ export class MinglarService { throw new ApiError(401, 'Invalid credentials'); } + if (existingUser?.profileImage) { + const key = existingUser.profileImage.startsWith("http") + ? existingUser.profileImage.split(".com/")[1] + : existingUser.profileImage; + + existingUser.profileImage = await getPresignedUrl(bucket, key); + } + + delete existingUser.userPassword; + return existingUser; } @@ -742,19 +764,36 @@ export class MinglarService { } /** APPLICATION STATUS FILTER (NEW) **/ - const APPLICATION_STATUS_MAP: Record = { - "New": MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW && MINGLAR_STATUS_DISPLAY.NEW, - "To_Review": MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW && MINGLAR_STATUS_DISPLAY.TO_REVIEW, - "Enchancing": MINGLAR_STATUS_INTERNAL.AM_REJECTED, + const APPLICATION_STATUS_MAP: Record< + string, + { internal: string; display: string } + > = { + New: { + internal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW, + display: MINGLAR_STATUS_DISPLAY.NEW, + }, + To_Review: { + internal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW, + display: MINGLAR_STATUS_DISPLAY.TO_REVIEW, + }, + Enhancing: { + internal: MINGLAR_STATUS_INTERNAL.AM_REJECTED, + display: MINGLAR_STATUS_DISPLAY.ENHANCING, + }, }; + if (applicationStatus?.trim()) { const key = applicationStatus.trim(); - if (APPLICATION_STATUS_MAP[key]) { - filters.adminStatusInternal = APPLICATION_STATUS_MAP[key]; + const statusObj = APPLICATION_STATUS_MAP[key]; + + if (statusObj) { + filters.adminStatusInternal = statusObj.internal; + filters.adminStatusDisplay = statusObj.display; } } + /** ROLE-BASED FILTER **/ if (userRoleXid === ROLE.CO_ADMIN || userRoleXid === ROLE.ACCOUNT_MANAGER) { filters.accountManagerXid = userId; @@ -1513,7 +1552,21 @@ export class MinglarService { async getAMdetailById(id: number) { const user = await this.prisma.user.findUnique({ where: { id: id, isActive: true, userStatus: USER_STATUS.ACTIVE }, - include: { + select: { + id: true, + firstName: true, + lastName: true, + emailAddress: true, + isdCode: true, + mobileNumber: true, + roleXid: true, + userStatus: true, + isProfileUpdated: true, + dateOfBirth: true, + profileImage: true, + isEmailVerfied: true, + isMobileVerfied: true, + isBiometric: true, userAddressDetails: { select: { id: true, diff --git a/src/modules/prepopulate/services/prepopulate.service.ts b/src/modules/prepopulate/services/prepopulate.service.ts index 7960a33..257df81 100644 --- a/src/modules/prepopulate/services/prepopulate.service.ts +++ b/src/modules/prepopulate/services/prepopulate.service.ts @@ -11,15 +11,11 @@ export class PrePopulateService { isActive: true, deletedAt: null, }, - include: { - BankBranches: { - select: { - id: true, - branchAddress: true, - ifscCode: true, - }, - }, + select: { + id: true, + bankName: true, }, + orderBy: { bankName: 'asc' } }); } @@ -28,7 +24,6 @@ export class PrePopulateService { where: { bankXid, isActive: true, - deletedAt: null }, select: { id: true, @@ -60,6 +55,12 @@ export class PrePopulateService { isActive: true, deletedAt: null, }, + select: { + id: true, + currencyName: true, + currencySymbol: true, + }, + orderBy: { currencyName: 'asc' } }); } @@ -68,27 +69,41 @@ export class PrePopulateService { where: { isActive: true }, include: { pqqsubCategories: { - include: { + where: { isActive: true }, + select: { + id: true, + subCategoryName: true, + categoryXid: true, + displayOrder: true, questions: { - include: { + where: { isActive: true }, + select: { + id: true, + questionName: true, + maxPoints: true, + displayOrder: true, PQQAnswers: { - orderBy: { - displayOrder: 'asc' + where: { isActive: true }, + orderBy: { displayOrder: 'asc' }, + select: { + id: true, + answerName: true, + answerPoints: true, + displayOrder: true } } }, - orderBy: { - displayOrder: 'asc' - } - } + orderBy: { displayOrder: 'asc' } + }, }, - orderBy: { displayOrder: 'asc' } - } + orderBy: { displayOrder: 'asc' }, + }, }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayOrder: 'asc' }, }); } + async getAllDocumentTypeWithCountryStateCity() { const [documentDetails, countryDetails, stateDetails, companyTypeDetails] = await this.prisma.$transaction([