diff --git a/apps/portal/src/utils/offers/analysis/analysisGeneration.ts b/apps/portal/src/utils/offers/analysis/analysisGeneration.ts index 4fa5f917..2181555d 100644 --- a/apps/portal/src/utils/offers/analysis/analysisGeneration.ts +++ b/apps/portal/src/utils/offers/analysis/analysisGeneration.ts @@ -57,88 +57,18 @@ const searchOfferPercentile = ( return -1; }; -export const generateAnalysis = async (params: { - ctx: { - prisma: PrismaClient< - Prisma.PrismaClientOptions, - never, - Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined - >; - session: Session | null; - }; - input: { profileId: string }; -}) => { - const { ctx, input } = params; - await ctx.prisma.offersAnalysis.deleteMany({ - where: { - profileId: input.profileId, - }, - }); - - const offers = await ctx.prisma.offersOffer.findMany({ - include: { - company: true, - location: { - include: { - state: { - include: { - country: true, - }, - }, - }, - }, - offersFullTime: { - include: { - baseSalary: true, - bonus: true, - stocks: true, - totalCompensation: true, - }, - }, - offersIntern: { - include: { - monthlySalary: true, - }, - }, - profile: { - include: { - background: true, - }, - }, - }, - orderBy: [ - { - offersFullTime: { - totalCompensation: { - baseValue: 'desc', - }, - }, - }, - { - offersIntern: { - monthlySalary: { - baseValue: 'desc', - }, - }, - }, - ], - where: { - profileId: input.profileId, - }, - }); - - if (!offers || offers.length === 0) { - throw new TRPCError({ - code: 'NOT_FOUND', - message: 'No offers found on this profile', - }); - } - - const overallHighestOffer = offers[0]; - +const getSimilarOffers = async ( + prisma: PrismaClient< + Prisma.PrismaClientOptions, + never, + Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined + >, + comparedOffer: Offer, + companyIdFilter: string | undefined, +) => { if ( - !overallHighestOffer.profile.background || - overallHighestOffer.profile.background.totalYoe == null + !comparedOffer.profile.background || + comparedOffer.profile.background.totalYoe == null ) { throw new TRPCError({ code: 'NOT_FOUND', @@ -146,11 +76,11 @@ export const generateAnalysis = async (params: { }); } - const yoe = overallHighestOffer.profile.background.totalYoe as number; - const monthYearReceived = new Date(overallHighestOffer.monthYearReceived); + const yoe = comparedOffer.profile.background.totalYoe as number; + const monthYearReceived = new Date(comparedOffer.monthYearReceived); monthYearReceived.setFullYear(monthYearReceived.getFullYear() - 1); - let similarOffers = await ctx.prisma.offersOffer.findMany({ + return await prisma.offersOffer.findMany({ include: { company: true, location: { @@ -214,7 +144,10 @@ export const generateAnalysis = async (params: { where: { AND: [ { - location: overallHighestOffer.location, + location: comparedOffer.location, + }, + { + companyId: companyIdFilter, }, { monthYearReceived: { @@ -225,10 +158,10 @@ export const generateAnalysis = async (params: { OR: [ { offersFullTime: { - title: overallHighestOffer.offersFullTime?.title, + title: comparedOffer.offersFullTime?.title, }, offersIntern: { - title: overallHighestOffer.offersIntern?.title, + title: comparedOffer.offersIntern?.title, }, }, ], @@ -250,6 +183,92 @@ export const generateAnalysis = async (params: { ], }, }); +}; + +export const generateAnalysis = async (params: { + ctx: { + prisma: PrismaClient< + Prisma.PrismaClientOptions, + never, + Prisma.RejectOnNotFound | Prisma.RejectPerOperation | undefined + >; + session: Session | null; + }; + input: { profileId: string }; +}) => { + const { ctx, input } = params; + await ctx.prisma.offersAnalysis.deleteMany({ + where: { + profileId: input.profileId, + }, + }); + + const offers = await ctx.prisma.offersOffer.findMany({ + include: { + company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, + offersFullTime: { + include: { + baseSalary: true, + bonus: true, + stocks: true, + totalCompensation: true, + }, + }, + offersIntern: { + include: { + monthlySalary: true, + }, + }, + profile: { + include: { + background: true, + }, + }, + }, + orderBy: [ + { + offersFullTime: { + totalCompensation: { + baseValue: 'desc', + }, + }, + }, + { + offersIntern: { + monthlySalary: { + baseValue: 'desc', + }, + }, + }, + ], + where: { + profileId: input.profileId, + }, + }); + + if (!offers || offers.length === 0) { + throw new TRPCError({ + code: 'NOT_FOUND', + message: 'No offers found on this profile', + }); + } + + const overallHighestOffer = offers[0]; + + let similarOffers = await getSimilarOffers( + ctx.prisma, + overallHighestOffer, + undefined, + ); const offerIds = offers.map((offer) => offer.id); @@ -261,11 +280,13 @@ export const generateAnalysis = async (params: { } }); - const companyAnalysis = Array.from(companyMap.values()).map( - (companyOffer) => { + const companyAnalysis = await Promise.all( + Array.from(companyMap.values()).map(async (companyOffer) => { // TODO: Refactor calculating analysis into a function - let similarCompanyOffers = similarOffers.filter( - (offer) => offer.companyId === companyOffer.companyId, + let similarCompanyOffers = await getSimilarOffers( + ctx.prisma, + companyOffer, + companyOffer.companyId, ); const companyIndex = searchOfferPercentile( @@ -300,7 +321,7 @@ export const generateAnalysis = async (params: { percentile: companyPercentile, topSimilarOffers: topPercentileCompanyOffers, }; - }, + }), ); // OVERALL ANALYSIS