diff --git a/src/modules/host/services/host.service.ts b/src/modules/host/services/host.service.ts index 8f85180..4a947af 100644 --- a/src/modules/host/services/host.service.ts +++ b/src/modules/host/services/host.service.ts @@ -39,7 +39,7 @@ interface HostDocumentInput { @Injectable() export class HostService { - constructor(private prisma: PrismaService) {} + constructor(private prisma: PrismaService) { } async createHost(data: CreateHostDto) { return this.prisma.user.create({ data }); @@ -720,119 +720,132 @@ export class HostService { // } async calculatePqqScoreForUser(activityXid: number) { - // 1. Get all headers for this activity (user's answers) - const answers = await this.prisma.activityPQQheader.findMany({ - where: { activityXid }, - include: { - pqqQuestions: { - include: { - pqqSubCategories: { - include: { - category: true, + return await this.prisma.$transaction(async (tx) => { + // 1. Get all headers for this activity (user's answers) + const answers = await this.prisma.activityPQQheader.findMany({ + where: { activityXid }, + include: { + pqqQuestions: { + include: { + pqqSubCategories: { + include: { + category: true, + }, }, }, }, + pqqAnswers: true, }, - pqqAnswers: true, - }, - }); + }); - if (!answers.length) { - return { - overallPercentage: 0, - categoryWise: {}, - }; - } - - // Prepare accumulators - let totalUserPoints = 0; - let totalMaxPoints = 0; - - // For category-wise scoring - const categories: Record< - number, - { - categoryId: number; - categoryName: string; - userPoints: number; - maxPoints: number; - } - > = {}; - - for (const item of answers) { - const question = item.pqqQuestions; - const answer = item.pqqAnswers; - - const maxPoints = question.maxPoints; - const userPoints = answer.answerPoints; - - totalUserPoints += userPoints; - totalMaxPoints += maxPoints; - - // Category - const category = question.pqqSubCategories.category; - const categoryId = category.id; - - if (!categories[categoryId]) { - categories[categoryId] = { - categoryId, - categoryName: category.categoryName, - userPoints: 0, - maxPoints: 0, + if (!answers.length) { + return { + overallPercentage: 0, + categoryWise: {}, }; } - categories[categoryId].userPoints += userPoints; - categories[categoryId].maxPoints += maxPoints; - } + // Prepare accumulators + let totalUserPoints = 0; + let totalMaxPoints = 0; - // Overall percent - const overallPercentage = - totalMaxPoints > 0 ? (totalUserPoints / totalMaxPoints) * 100 : 0; + // For category-wise scoring + const categories: Record< + number, + { + categoryId: number; + categoryName: string; + userPoints: number; + maxPoints: number; + } + > = {}; + + for (const item of answers) { + const question = item.pqqQuestions; + const answer = item.pqqAnswers; + + const maxPoints = question.maxPoints; + const userPoints = answer.answerPoints; + + totalUserPoints += userPoints; + totalMaxPoints += maxPoints; + + // Category + const category = question.pqqSubCategories.category; + const categoryId = category.id; + + if (!categories[categoryId]) { + categories[categoryId] = { + categoryId, + categoryName: category.categoryName, + userPoints: 0, + maxPoints: 0, + }; + } + + categories[categoryId].userPoints += userPoints; + categories[categoryId].maxPoints += maxPoints; + } + + // Overall percent + const overallPercentage = + totalMaxPoints > 0 ? (totalUserPoints / totalMaxPoints) * 100 : 0; + + if (overallPercentage > 50) { + await this.prisma.activities.update({ + where: { + id: activityXid + }, + data: { + activityInternalStatus: ACTIVITY_INTERNAL_STATUS.UNDER_REVIEW, + activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.UNDER_REVIEW + } + }) + } else { + await this.prisma.activities.update({ + where: { + id: activityXid + }, + data: { + activityInternalStatus: ACTIVITY_INTERNAL_STATUS.PQQ_FAILED, + activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.PQQ_FAILED + } + }) + } + + // ---------- 🔥 ONLY FIRST 2 CATEGORIES ---------- + const categoryArray = Object.values(categories); + + // Sort by categoryId (or change to displayOrder if needed) + categoryArray.sort((a, b) => a.categoryId - b.categoryId); + + // Take only first 2 categories + const topTwo = categoryArray.slice(0, 2); + + const categoryWise: Record = {}; + + for (const c of topTwo) { + categoryWise[c.categoryName] = + c.maxPoints > 0 ? (c.userPoints / c.maxPoints) * 100 : 0; + } - if (overallPercentage > 50) { await this.prisma.activities.update({ where: { id: activityXid }, data: { - activityInternalStatus: ACTIVITY_INTERNAL_STATUS.UNDER_REVIEW, - activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.UNDER_REVIEW + totalScore: overallPercentage, + sustainabilityScore: categoryWise.Sustainability, + safetyScore: categoryWise.Safety } }) - } else { - await this.prisma.activities.update({ - where: { - id: activityXid - }, - data: { - activityInternalStatus: ACTIVITY_INTERNAL_STATUS.PQQ_FAILED, - activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.PQQ_FAILED - } - }) - } - // ---------- 🔥 ONLY FIRST 2 CATEGORIES ---------- - const categoryArray = Object.values(categories); - - // Sort by categoryId (or change to displayOrder if needed) - categoryArray.sort((a, b) => a.categoryId - b.categoryId); - - // Take only first 2 categories - const topTwo = categoryArray.slice(0, 2); - - const categoryWise: Record = {}; - - for (const c of topTwo) { - categoryWise[c.categoryName] = - c.maxPoints > 0 ? (c.userPoints / c.maxPoints) * 100 : 0; - } - - // Return final score object - return { - overallPercentage, - categoryWise, - }; + // Return final score object + return { + overallPercentage, + categoryWise, + }; + }); } async createHeader( @@ -927,10 +940,52 @@ export class HostService { return await this.prisma.activityPQQheader.findMany({ where: { isActive: true }, include: { - pqqQuestions: true, - ActivityPQQSuggestions: true, - pqqAnswers: true, - ActivityPQQSupportings: true, + pqqQuestions: { + select: { + questionName: true, + maxPoints: true, + displayOrder: true, + pqqSubCategories: { + select: { + id: true, + subCategoryName: true, + displayOrder: true, + category: { + select: { + id: true, + categoryName: true, + displayOrder: true, + } + } + } + } + } + }, + ActivityPQQSuggestions: { + select: { + id: true, + title: true, + comments: true, + isReviewed: true, + reviewedBy: true, + reviewedOn: true, + } + }, + pqqAnswers: { + select: { + id: true, + displayOrder: true, + answerName: true, + answerPoints: true + } + }, + ActivityPQQSupportings: { + select: { + id: true, + mediaFileName: true, + mediaType: true, + } + }, }, }); } diff --git a/src/modules/minglaradmin/handlers/hosthub/onboarding/getAllActivityOfHost.ts b/src/modules/minglaradmin/handlers/hosthub/onboarding/getAllActivityOfHost.ts index 0c1a991..d63895d 100644 --- a/src/modules/minglaradmin/handlers/hosthub/onboarding/getAllActivityOfHost.ts +++ b/src/modules/minglaradmin/handlers/hosthub/onboarding/getAllActivityOfHost.ts @@ -1,11 +1,10 @@ +import { verifyMinglarAdminToken } from '@/common/middlewares/jwt/authForMinglarAdmin'; import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; import { PrismaService } from '../../../../../common/database/prisma.service'; import { safeHandler } from '../../../../../common/utils/handlers/safeHandler'; import ApiError from '../../../../../common/utils/helper/ApiError'; -import { string } from 'zod'; import { PrePopulateService } from '../../../../prepopulate/services/prepopulate.service'; import { MinglarService } from '../../../services/minglar.service'; -import { verifyMinglarAdminHostToken } from '@/common/middlewares/jwt/authForMinglarAdmin&Host'; const prismaService = new PrismaService(); const minglarService = new MinglarService(prismaService); @@ -27,7 +26,7 @@ export const handler = safeHandler(async ( } // Verify token and get user info - const userInfo = await verifyMinglarAdminHostToken(token); + const userInfo = await verifyMinglarAdminToken(token); const hostXid = Number(event.pathParameters?.id) diff --git a/src/modules/minglaradmin/services/minglar.service.ts b/src/modules/minglaradmin/services/minglar.service.ts index 5b07545..d4f325b 100644 --- a/src/modules/minglaradmin/services/minglar.service.ts +++ b/src/modules/minglaradmin/services/minglar.service.ts @@ -23,7 +23,7 @@ import { sendAMEmailForHostAssign } from './AMEmail.service'; @Injectable() export class MinglarService { - constructor(private prisma: PrismaService) {} + constructor(private prisma: PrismaService) { } async createPassword(user_xid: number, password: string): Promise { // Find user by id @@ -203,16 +203,36 @@ export class MinglarService { } async getAllHostActivityForMinglar(search?: string, hostXid?: number) { - return await this.prisma.activities.findMany({ + return await this.prisma.activities.findMany({ where: { isActive: true, hostXid: hostXid, }, include: { - ActivitiesMedia: true, - ActivityAmDetails: true, + ActivitiesMedia: { + select: { + id: true, + mediaFileName: true, + mediaType: true, + displayOrder: true, + } + }, + ActivityAmDetails: { + select: { + accountManager: { + select: { + id: true, + firstName: true, + lastName: true, + profileImage: true, + emailAddress: true, + roleXid: true, + } + } + } + }, activityType: true, - }, + }, }); } @@ -614,7 +634,7 @@ export class MinglarService { if ( userStatus && userStatus.trim().toLowerCase() === - MINGLAR_STATUS_DISPLAY.NEW.toLowerCase() + MINGLAR_STATUS_DISPLAY.NEW.toLowerCase() ) { filters.adminStatusInternal = MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW; } @@ -872,7 +892,7 @@ export class MinglarService { if ( hostDetails.adminStatusInternal !== - MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED && + MINGLAR_STATUS_INTERNAL.AM_NOT_ASSIGNED && hostDetails.adminStatusDisplay !== MINGLAR_STATUS_DISPLAY.AM_NOT_ASSIGNED ) { throw new ApiError(400, 'Invalid host status');