mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 04:33:42 +08:00
[offers][chore] Add a relative base value to the currency model in schema
This commit is contained in:
12
apps/portal/prisma/migrations/20221021231817_/migration.sql
Normal file
12
apps/portal/prisma/migrations/20221021231817_/migration.sql
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `baseValue` to the `OffersCurrency` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `updatedAt` to the `OffersCurrency` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "OffersCurrency" ADD COLUMN "baseCurrency" TEXT NOT NULL DEFAULT 'USD',
|
||||
ADD COLUMN "baseValue" INTEGER NOT NULL,
|
||||
ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
|
@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "OffersCurrency" ALTER COLUMN "value" SET DATA TYPE DOUBLE PRECISION,
|
||||
ALTER COLUMN "baseValue" SET DATA TYPE DOUBLE PRECISION;
|
@ -205,9 +205,9 @@ model OffersBackground {
|
||||
totalYoe Int
|
||||
specificYoes OffersSpecificYoe[]
|
||||
|
||||
experiences OffersExperience[] // For extensibility in the future
|
||||
experiences OffersExperience[]
|
||||
|
||||
educations OffersEducation[] // For extensibility in the future
|
||||
educations OffersEducation[]
|
||||
|
||||
profile OffersProfile @relation(fields: [offersProfileId], references: [id], onDelete: Cascade)
|
||||
offersProfileId String @unique
|
||||
@ -251,10 +251,16 @@ model OffersExperience {
|
||||
}
|
||||
|
||||
model OffersCurrency {
|
||||
id String @id @default(cuid())
|
||||
value Int
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
value Float
|
||||
currency String
|
||||
|
||||
baseValue Float
|
||||
baseCurrency String @default("USD")
|
||||
|
||||
// Experience
|
||||
OffersExperienceTotalCompensation OffersExperience? @relation("ExperienceTotalCompensation")
|
||||
OffersExperienceMonthlySalary OffersExperience? @relation("ExperienceMonthlySalary")
|
||||
|
@ -40,7 +40,7 @@ function Test() {
|
||||
deleteCommentMutation.mutate({
|
||||
id: 'cl97fprun001j7iyg6ev9x983',
|
||||
profileId: 'cl96stky5002ew32gx2kale2x',
|
||||
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1',
|
||||
token: '24bafa6fef803f447d7f2e229b14cb8ee43f0c22dffbe41ee1c1e5e6e870f117',
|
||||
userId: 'cl97dl51k001e7iygd5v5gt58',
|
||||
});
|
||||
};
|
||||
@ -84,7 +84,7 @@ function Test() {
|
||||
const handleLink = () => {
|
||||
addToUserProfileMutation.mutate({
|
||||
profileId: 'cl9efyn9p004ww3u42mjgl1vn',
|
||||
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba',
|
||||
token: '24bafa6fef803f447d7f2e229b14cb8ee43f0c22dffbe41ee1c1e5e6e870f117',
|
||||
userId: 'cl9ehvpng0000w3ec2mpx0bdd',
|
||||
});
|
||||
};
|
||||
@ -103,11 +103,10 @@ function Test() {
|
||||
],
|
||||
experiences: [
|
||||
{
|
||||
companyId: 'cl9h0bqu50000txxwkhmshhxz',
|
||||
companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
durationInMonths: 24,
|
||||
jobType: 'FULLTIME',
|
||||
level: 'Junior',
|
||||
// "monthlySalary": undefined,
|
||||
specialization: 'Front End',
|
||||
title: 'Software Engineer',
|
||||
totalCompensation: {
|
||||
@ -132,7 +131,7 @@ function Test() {
|
||||
{
|
||||
comments: 'I am a Raffles Institution almumni',
|
||||
// Comments: '',
|
||||
companyId: 'cl9h0bqu50000txxwkhmshhxz',
|
||||
companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
jobType: 'FULLTIME',
|
||||
location: 'Singapore, Singapore',
|
||||
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
|
||||
@ -161,7 +160,7 @@ function Test() {
|
||||
},
|
||||
{
|
||||
comments: '',
|
||||
companyId: 'cl9h0bqu50000txxwkhmshhxz',
|
||||
companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
jobType: 'FULLTIME',
|
||||
location: 'Singapore, Singapore',
|
||||
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
|
||||
@ -192,14 +191,14 @@ function Test() {
|
||||
});
|
||||
};
|
||||
|
||||
const profileId = 'cl9i68fv60000tthj8t3zkox0'; // Remember to change this filed after testing deleting
|
||||
const profileId = 'cl9j50xzk008vutfqg6mta2ey'; // Remember to change this filed after testing deleting
|
||||
const data = trpc.useQuery(
|
||||
[
|
||||
`offers.profile.listOne`,
|
||||
{
|
||||
profileId,
|
||||
token:
|
||||
'd14666ff76e267c9e99445844b41410e83874936d0c07e664db73ff0ea76919e',
|
||||
'24bafa6fef803f447d7f2e229b14cb8ee43f0c22dffbe41ee1c1e5e6e870f117',
|
||||
},
|
||||
],
|
||||
{
|
||||
@ -223,7 +222,7 @@ function Test() {
|
||||
const handleDelete = (id: string) => {
|
||||
deleteMutation.mutate({
|
||||
profileId: id,
|
||||
token: 'e7effd2a40adba2deb1ddea4fb9f1e6c3c98ab0a85a88ed1567fc2a107fdb445',
|
||||
token: '24bafa6fef803f447d7f2e229b14cb8ee43f0c22dffbe41ee1c1e5e6e870f117',
|
||||
});
|
||||
};
|
||||
|
||||
@ -257,15 +256,15 @@ function Test() {
|
||||
createdAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
description:
|
||||
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
|
||||
id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
logoUrl: 'https://logo.clearbit.com/meta.com',
|
||||
name: 'Meta',
|
||||
slug: 'meta',
|
||||
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
},
|
||||
companyId: 'cl9h0bqug0003txxwgkac0x40',
|
||||
companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
durationInMonths: 24,
|
||||
// Id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// Id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
jobType: 'FULLTIME',
|
||||
level: 'Junior',
|
||||
monthlySalary: null,
|
||||
@ -309,13 +308,13 @@ function Test() {
|
||||
createdAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
description:
|
||||
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
|
||||
id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
logoUrl: 'https://logo.clearbit.com/meta.com',
|
||||
name: 'Meta',
|
||||
slug: 'meta',
|
||||
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
},
|
||||
companyId: 'cl9h0bqug0003txxwgkac0x40',
|
||||
companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
id: 'cl9i68fve000ntthj5h9yvqnh',
|
||||
jobType: 'FULLTIME',
|
||||
location: 'Singapore, Singapore',
|
||||
@ -362,13 +361,13 @@ function Test() {
|
||||
// createdAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// description:
|
||||
// 'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
|
||||
// id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// logoUrl: 'https://logo.clearbit.com/meta.com',
|
||||
// name: 'Meta',
|
||||
// slug: 'meta',
|
||||
// updatedAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// },
|
||||
// companyId: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// id: 'cl9i68fvf000ytthj0ltsqt1d',
|
||||
// jobType: 'FULLTIME',
|
||||
// location: 'Singapore, Singapore',
|
||||
@ -415,13 +414,13 @@ function Test() {
|
||||
// createdAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// description:
|
||||
// 'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
|
||||
// id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// logoUrl: 'https://logo.clearbit.com/meta.com',
|
||||
// name: 'Meta',
|
||||
// slug: 'meta',
|
||||
// updatedAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// },
|
||||
// companyId: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// id: 'cl96stky9003bw32gc3l955vr',
|
||||
// jobType: 'FULLTIME',
|
||||
// location: 'Singapore, Singapore',
|
||||
@ -468,13 +467,13 @@ function Test() {
|
||||
// createdAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// description:
|
||||
// 'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
|
||||
// id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// logoUrl: 'https://logo.clearbit.com/meta.com',
|
||||
// name: 'Meta',
|
||||
// slug: 'meta',
|
||||
// updatedAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// },
|
||||
// companyId: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// id: 'cl976wf28000t7iyga4noyz7s',
|
||||
// jobType: 'FULLTIME',
|
||||
// location: 'Singapore, Singapore',
|
||||
@ -521,13 +520,13 @@ function Test() {
|
||||
// createdAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// description:
|
||||
// 'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
|
||||
// id: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// id: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// logoUrl: 'https://logo.clearbit.com/meta.com',
|
||||
// name: 'Meta',
|
||||
// slug: 'meta',
|
||||
// updatedAt: new Date('2022-10-12T16:19:05.196Z'),
|
||||
// },
|
||||
// companyId: 'cl9h0bqug0003txxwgkac0x40',
|
||||
// companyId: 'cl9j4yawz0003utlp1uaa1t8o',
|
||||
// id: 'cl96tbb3o0051w32gjrpaiiit',
|
||||
// jobType: 'FULLTIME',
|
||||
// location: 'Singapore, Singapore',
|
||||
@ -570,7 +569,7 @@ function Test() {
|
||||
// },
|
||||
],
|
||||
// ProfileName: 'ailing bryann stuart ziqing',
|
||||
token: 'd3509cb890f0bae0a785afdd6c1c074a140706ab1d155ed338ec22dcca5c92f1',
|
||||
token: '24bafa6fef803f447d7f2e229b14cb8ee43f0c22dffbe41ee1c1e5e6e870f117',
|
||||
userId: null,
|
||||
});
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import crypto, { randomUUID } from 'crypto';
|
||||
import { z } from 'zod';
|
||||
import { JobType } from '@prisma/client';
|
||||
import * as trpc from '@trpc/server';
|
||||
|
||||
import {
|
||||
@ -7,6 +8,9 @@ import {
|
||||
createOfferProfileResponseMapper,
|
||||
profileDtoMapper,
|
||||
} from '~/mappers/offers-mappers';
|
||||
import { baseCurrencyString } from '~/utils/offers/currency';
|
||||
import { convert } from '~/utils/offers/currency/currency-exchange';
|
||||
import { createValidationRegex } from '~/utils/offers/zodRegex';
|
||||
|
||||
import { createRouter } from '../context';
|
||||
|
||||
@ -31,7 +35,7 @@ const offer = z.object({
|
||||
company: company.nullish(),
|
||||
companyId: z.string(),
|
||||
id: z.string().optional(),
|
||||
jobType: z.string(),
|
||||
jobType: z.string().regex(createValidationRegex(Object.keys(JobType), null)),
|
||||
location: z.string(),
|
||||
monthYearReceived: z.date(),
|
||||
negotiationStrategy: z.string(),
|
||||
@ -73,7 +77,10 @@ const experience = z.object({
|
||||
companyId: z.string().nullish(),
|
||||
durationInMonths: z.number().nullish(),
|
||||
id: z.string().optional(),
|
||||
jobType: z.string().nullish(),
|
||||
jobType: z
|
||||
.string()
|
||||
.regex(createValidationRegex(Object.keys(JobType), null))
|
||||
.nullish(),
|
||||
level: z.string().nullish(),
|
||||
location: z.string().nullish(),
|
||||
monthlySalary: valuation.nullish(),
|
||||
@ -94,15 +101,6 @@ const education = z.object({
|
||||
type: z.string().nullish(),
|
||||
});
|
||||
|
||||
// Const reply = z.object({
|
||||
// createdAt: z.date().nullish(),
|
||||
// id: z.string().optional(),
|
||||
// messages: z.string().nullish(),
|
||||
// profileId: z.string().nullish(),
|
||||
// replyingToId: z.string().nullish(),
|
||||
// userId: z.string().nullish(),
|
||||
// });
|
||||
|
||||
export const offersProfileRouter = createRouter()
|
||||
.query('listOne', {
|
||||
input: z.object({
|
||||
@ -282,11 +280,11 @@ export const offersProfileRouter = createRouter()
|
||||
})),
|
||||
},
|
||||
experiences: {
|
||||
create: input.background.experiences.map((x) => {
|
||||
create: input.background.experiences.map(async (x) => {
|
||||
if (
|
||||
x.jobType === 'FULLTIME' &&
|
||||
x.totalCompensation?.currency !== undefined &&
|
||||
x.totalCompensation.value !== undefined
|
||||
x.jobType === JobType.FULLTIME &&
|
||||
x.totalCompensation?.currency != null &&
|
||||
x.totalCompensation?.value != null
|
||||
) {
|
||||
if (x.companyId) {
|
||||
return {
|
||||
@ -302,8 +300,14 @@ export const offersProfileRouter = createRouter()
|
||||
title: x.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: x.totalCompensation?.currency,
|
||||
value: x.totalCompensation?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.totalCompensation.value,
|
||||
x.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.totalCompensation.currency,
|
||||
value: x.totalCompensation.value,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -312,20 +316,27 @@ export const offersProfileRouter = createRouter()
|
||||
durationInMonths: x.durationInMonths,
|
||||
jobType: x.jobType,
|
||||
level: x.level,
|
||||
location: x.location,
|
||||
specialization: x.specialization,
|
||||
title: x.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: x.totalCompensation?.currency,
|
||||
value: x.totalCompensation?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.totalCompensation.value,
|
||||
x.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.totalCompensation.currency,
|
||||
value: x.totalCompensation.value,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
if (
|
||||
x.jobType === 'INTERN' &&
|
||||
x.monthlySalary?.currency !== undefined &&
|
||||
x.monthlySalary.value !== undefined
|
||||
x.jobType === JobType.INTERN &&
|
||||
x.monthlySalary?.currency != null &&
|
||||
x.monthlySalary?.value != null
|
||||
) {
|
||||
if (x.companyId) {
|
||||
return {
|
||||
@ -338,8 +349,14 @@ export const offersProfileRouter = createRouter()
|
||||
jobType: x.jobType,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.monthlySalary?.currency,
|
||||
value: x.monthlySalary?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.monthlySalary.value,
|
||||
x.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.monthlySalary.currency,
|
||||
value: x.monthlySalary.value,
|
||||
},
|
||||
},
|
||||
specialization: x.specialization,
|
||||
@ -351,8 +368,14 @@ export const offersProfileRouter = createRouter()
|
||||
jobType: x.jobType,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.monthlySalary?.currency,
|
||||
value: x.monthlySalary?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.monthlySalary.value,
|
||||
x.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.monthlySalary.currency,
|
||||
value: x.monthlySalary.value,
|
||||
},
|
||||
},
|
||||
specialization: x.specialization,
|
||||
@ -379,107 +402,141 @@ export const offersProfileRouter = createRouter()
|
||||
},
|
||||
editToken: token,
|
||||
offers: {
|
||||
create: input.offers.map((x) => {
|
||||
if (
|
||||
x.jobType === 'INTERN' &&
|
||||
x.offersIntern &&
|
||||
x.offersIntern.internshipCycle &&
|
||||
x.offersIntern.monthlySalary?.currency &&
|
||||
x.offersIntern.monthlySalary.value &&
|
||||
x.offersIntern.startYear
|
||||
) {
|
||||
return {
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
create: await Promise.all(
|
||||
input.offers.map(async (x) => {
|
||||
if (
|
||||
x.jobType === JobType.INTERN &&
|
||||
x.offersIntern &&
|
||||
x.offersIntern.internshipCycle != null &&
|
||||
x.offersIntern.monthlySalary?.currency != null &&
|
||||
x.offersIntern.monthlySalary?.value != null &&
|
||||
x.offersIntern.startYear != null
|
||||
) {
|
||||
return {
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
},
|
||||
},
|
||||
},
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy,
|
||||
offersIntern: {
|
||||
create: {
|
||||
internshipCycle: x.offersIntern.internshipCycle,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.offersIntern.monthlySalary?.currency,
|
||||
value: x.offersIntern.monthlySalary?.value,
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy,
|
||||
offersIntern: {
|
||||
create: {
|
||||
internshipCycle: x.offersIntern.internshipCycle,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.offersIntern.monthlySalary.value,
|
||||
x.offersIntern.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.offersIntern.monthlySalary.currency,
|
||||
value: x.offersIntern.monthlySalary.value,
|
||||
},
|
||||
},
|
||||
specialization: x.offersIntern.specialization,
|
||||
startYear: x.offersIntern.startYear,
|
||||
title: x.offersIntern.title,
|
||||
},
|
||||
specialization: x.offersIntern.specialization,
|
||||
startYear: x.offersIntern.startYear,
|
||||
title: x.offersIntern.title,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
if (
|
||||
x.jobType === 'FULLTIME' &&
|
||||
x.offersFullTime &&
|
||||
x.offersFullTime.baseSalary?.currency &&
|
||||
x.offersFullTime.baseSalary?.value &&
|
||||
x.offersFullTime.bonus?.currency &&
|
||||
x.offersFullTime.bonus?.value &&
|
||||
x.offersFullTime.stocks?.currency &&
|
||||
x.offersFullTime.stocks?.value &&
|
||||
x.offersFullTime.totalCompensation?.currency &&
|
||||
x.offersFullTime.totalCompensation?.value &&
|
||||
x.offersFullTime.level
|
||||
) {
|
||||
return {
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
};
|
||||
}
|
||||
if (
|
||||
x.jobType === JobType.FULLTIME &&
|
||||
x.offersFullTime &&
|
||||
x.offersFullTime.baseSalary?.currency != null &&
|
||||
x.offersFullTime.baseSalary?.value != null &&
|
||||
x.offersFullTime.bonus?.currency != null &&
|
||||
x.offersFullTime.bonus?.value != null &&
|
||||
x.offersFullTime.stocks?.currency != null &&
|
||||
x.offersFullTime.stocks?.value != null &&
|
||||
x.offersFullTime.totalCompensation?.currency != null &&
|
||||
x.offersFullTime.totalCompensation?.value != null &&
|
||||
x.offersFullTime.level != null &&
|
||||
x.offersFullTime.title != null &&
|
||||
x.offersFullTime.specialization != null
|
||||
) {
|
||||
return {
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
},
|
||||
},
|
||||
},
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy,
|
||||
offersFullTime: {
|
||||
create: {
|
||||
baseSalary: {
|
||||
create: {
|
||||
currency: x.offersFullTime.baseSalary?.currency,
|
||||
value: x.offersFullTime.baseSalary?.value,
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy,
|
||||
offersFullTime: {
|
||||
create: {
|
||||
baseSalary: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.offersFullTime.baseSalary.value,
|
||||
x.offersFullTime.baseSalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.offersFullTime.baseSalary.currency,
|
||||
value: x.offersFullTime.baseSalary.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
bonus: {
|
||||
create: {
|
||||
currency: x.offersFullTime.bonus?.currency,
|
||||
value: x.offersFullTime.bonus?.value,
|
||||
bonus: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.offersFullTime.bonus.value,
|
||||
x.offersFullTime.bonus.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.offersFullTime.bonus.currency,
|
||||
value: x.offersFullTime.bonus.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
level: x.offersFullTime.level,
|
||||
specialization: x.offersFullTime.specialization,
|
||||
stocks: {
|
||||
create: {
|
||||
currency: x.offersFullTime.stocks?.currency,
|
||||
value: x.offersFullTime.stocks?.value,
|
||||
level: x.offersFullTime.level,
|
||||
specialization: x.offersFullTime.specialization,
|
||||
stocks: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.offersFullTime.stocks.value,
|
||||
x.offersFullTime.stocks.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: x.offersFullTime.stocks.currency,
|
||||
value: x.offersFullTime.stocks.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
title: x.offersFullTime.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency:
|
||||
x.offersFullTime.totalCompensation?.currency,
|
||||
value: x.offersFullTime.totalCompensation?.value,
|
||||
title: x.offersFullTime.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
x.offersFullTime.totalCompensation.value,
|
||||
x.offersFullTime.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
x.offersFullTime.totalCompensation.currency,
|
||||
value: x.offersFullTime.totalCompensation.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Throw error
|
||||
throw new trpc.TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'Missing fields.',
|
||||
});
|
||||
}),
|
||||
// Throw error
|
||||
throw new trpc.TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'Missing fields.',
|
||||
});
|
||||
}),
|
||||
),
|
||||
},
|
||||
profileName: randomUUID().substring(0, 10),
|
||||
},
|
||||
@ -510,7 +567,7 @@ export const offersProfileRouter = createRouter()
|
||||
|
||||
return deletedProfile.id;
|
||||
}
|
||||
// TODO: Throw 401
|
||||
|
||||
throw new trpc.TRPCError({
|
||||
code: 'UNAUTHORIZED',
|
||||
message: 'Invalid token.',
|
||||
@ -535,7 +592,6 @@ export const offersProfileRouter = createRouter()
|
||||
totalYoe: z.number(),
|
||||
}),
|
||||
createdAt: z.string().optional(),
|
||||
// Discussion: z.array(reply),
|
||||
id: z.string(),
|
||||
isEditable: z.boolean().nullish(),
|
||||
offers: z.array(offer),
|
||||
@ -573,19 +629,21 @@ export const offersProfileRouter = createRouter()
|
||||
});
|
||||
|
||||
// Delete educations
|
||||
const educationsId = (await ctx.prisma.offersEducation.findMany({
|
||||
where: {
|
||||
backgroundId: input.background.id
|
||||
}
|
||||
})).map((x) => x.id)
|
||||
const educationsId = (
|
||||
await ctx.prisma.offersEducation.findMany({
|
||||
where: {
|
||||
backgroundId: input.background.id,
|
||||
},
|
||||
})
|
||||
).map((x) => x.id);
|
||||
|
||||
for (const id of educationsId) {
|
||||
if (!input.background.educations.map((x) => x.id).includes(id)) {
|
||||
await ctx.prisma.offersEducation.delete({
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -626,19 +684,21 @@ export const offersProfileRouter = createRouter()
|
||||
}
|
||||
|
||||
// Delete experiences
|
||||
const experiencesId = (await ctx.prisma.offersExperience.findMany({
|
||||
where: {
|
||||
backgroundId: input.background.id
|
||||
}
|
||||
})).map((x) => x.id)
|
||||
const experiencesId = (
|
||||
await ctx.prisma.offersExperience.findMany({
|
||||
where: {
|
||||
backgroundId: input.background.id,
|
||||
},
|
||||
})
|
||||
).map((x) => x.id);
|
||||
|
||||
for (const id of experiencesId) {
|
||||
if (!input.background.experiences.map((x) => x.id).includes(id)) {
|
||||
await ctx.prisma.offersExperience.delete({
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -660,6 +720,12 @@ export const offersProfileRouter = createRouter()
|
||||
if (exp.monthlySalary) {
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
exp.monthlySalary.value,
|
||||
exp.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: exp.monthlySalary.currency,
|
||||
value: exp.monthlySalary.value,
|
||||
},
|
||||
@ -672,6 +738,12 @@ export const offersProfileRouter = createRouter()
|
||||
if (exp.totalCompensation) {
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
exp.totalCompensation.value,
|
||||
exp.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: exp.totalCompensation.currency,
|
||||
value: exp.totalCompensation.value,
|
||||
},
|
||||
@ -683,9 +755,9 @@ export const offersProfileRouter = createRouter()
|
||||
} else if (!exp.id) {
|
||||
// Create new experience
|
||||
if (
|
||||
exp.jobType === 'FULLTIME' &&
|
||||
exp.totalCompensation?.currency !== undefined &&
|
||||
exp.totalCompensation.value !== undefined
|
||||
exp.jobType === JobType.FULLTIME &&
|
||||
exp.totalCompensation?.currency != null &&
|
||||
exp.totalCompensation?.value != null
|
||||
) {
|
||||
if (exp.companyId) {
|
||||
await ctx.prisma.offersBackground.update({
|
||||
@ -700,12 +772,19 @@ export const offersProfileRouter = createRouter()
|
||||
durationInMonths: exp.durationInMonths,
|
||||
jobType: exp.jobType,
|
||||
level: exp.level,
|
||||
location: exp.location,
|
||||
specialization: exp.specialization,
|
||||
title: exp.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: exp.totalCompensation?.currency,
|
||||
value: exp.totalCompensation?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
exp.totalCompensation.value,
|
||||
exp.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: exp.totalCompensation.currency,
|
||||
value: exp.totalCompensation.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -723,12 +802,19 @@ export const offersProfileRouter = createRouter()
|
||||
durationInMonths: exp.durationInMonths,
|
||||
jobType: exp.jobType,
|
||||
level: exp.level,
|
||||
location: exp.location,
|
||||
specialization: exp.specialization,
|
||||
title: exp.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: exp.totalCompensation?.currency,
|
||||
value: exp.totalCompensation?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
exp.totalCompensation.value,
|
||||
exp.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: exp.totalCompensation.currency,
|
||||
value: exp.totalCompensation.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -740,9 +826,9 @@ export const offersProfileRouter = createRouter()
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
exp.jobType === 'INTERN' &&
|
||||
exp.monthlySalary?.currency !== undefined &&
|
||||
exp.monthlySalary.value !== undefined
|
||||
exp.jobType === JobType.INTERN &&
|
||||
exp.monthlySalary?.currency != null &&
|
||||
exp.monthlySalary?.value != null
|
||||
) {
|
||||
if (exp.companyId) {
|
||||
await ctx.prisma.offersBackground.update({
|
||||
@ -756,10 +842,17 @@ export const offersProfileRouter = createRouter()
|
||||
},
|
||||
durationInMonths: exp.durationInMonths,
|
||||
jobType: exp.jobType,
|
||||
location: exp.location,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: exp.monthlySalary?.currency,
|
||||
value: exp.monthlySalary?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
exp.monthlySalary.value,
|
||||
exp.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: exp.monthlySalary.currency,
|
||||
value: exp.monthlySalary.value,
|
||||
},
|
||||
},
|
||||
specialization: exp.specialization,
|
||||
@ -778,10 +871,17 @@ export const offersProfileRouter = createRouter()
|
||||
create: {
|
||||
durationInMonths: exp.durationInMonths,
|
||||
jobType: exp.jobType,
|
||||
location: exp.location,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: exp.monthlySalary?.currency,
|
||||
value: exp.monthlySalary?.value,
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
exp.monthlySalary.value,
|
||||
exp.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: exp.monthlySalary.currency,
|
||||
value: exp.monthlySalary.value,
|
||||
},
|
||||
},
|
||||
specialization: exp.specialization,
|
||||
@ -799,19 +899,21 @@ export const offersProfileRouter = createRouter()
|
||||
}
|
||||
|
||||
// Delete specific yoes
|
||||
const yoesId = (await ctx.prisma.offersSpecificYoe.findMany({
|
||||
where: {
|
||||
backgroundId: input.background.id
|
||||
}
|
||||
})).map((x) => x.id)
|
||||
const yoesId = (
|
||||
await ctx.prisma.offersSpecificYoe.findMany({
|
||||
where: {
|
||||
backgroundId: input.background.id,
|
||||
},
|
||||
})
|
||||
).map((x) => x.id);
|
||||
|
||||
for (const id of yoesId) {
|
||||
if (!input.background.specificYoes.map((x) => x.id).includes(id)) {
|
||||
await ctx.prisma.offersSpecificYoe.delete({
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -845,19 +947,21 @@ export const offersProfileRouter = createRouter()
|
||||
}
|
||||
|
||||
// Delete specific offers
|
||||
const offers = (await ctx.prisma.offersOffer.findMany({
|
||||
where: {
|
||||
profileId: input.id
|
||||
}
|
||||
})).map((x) => x.id)
|
||||
const offers = (
|
||||
await ctx.prisma.offersOffer.findMany({
|
||||
where: {
|
||||
profileId: input.id,
|
||||
},
|
||||
})
|
||||
).map((x) => x.id);
|
||||
|
||||
for (const id of offers) {
|
||||
if (!input.offers.map((x) => x.id).includes(id)) {
|
||||
await ctx.prisma.offersOffer.delete({
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -869,6 +973,10 @@ export const offersProfileRouter = createRouter()
|
||||
data: {
|
||||
comments: offerToUpdate.comments,
|
||||
companyId: offerToUpdate.companyId,
|
||||
jobType:
|
||||
offerToUpdate.jobType === JobType.FULLTIME
|
||||
? JobType.FULLTIME
|
||||
: JobType.INTERN,
|
||||
location: offerToUpdate.location,
|
||||
monthYearReceived: offerToUpdate.monthYearReceived,
|
||||
negotiationStrategy: offerToUpdate.negotiationStrategy,
|
||||
@ -878,21 +986,7 @@ export const offersProfileRouter = createRouter()
|
||||
},
|
||||
});
|
||||
|
||||
if (
|
||||
offerToUpdate.jobType === 'INTERN' ||
|
||||
offerToUpdate.jobType === 'FULLTIME'
|
||||
) {
|
||||
await ctx.prisma.offersOffer.update({
|
||||
data: {
|
||||
jobType: offerToUpdate.jobType,
|
||||
},
|
||||
where: {
|
||||
id: offerToUpdate.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (offerToUpdate.offersIntern?.monthlySalary) {
|
||||
if (offerToUpdate.offersIntern?.monthlySalary != null) {
|
||||
await ctx.prisma.offersIntern.update({
|
||||
data: {
|
||||
internshipCycle:
|
||||
@ -907,6 +1001,12 @@ export const offersProfileRouter = createRouter()
|
||||
});
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersIntern.monthlySalary.value,
|
||||
offerToUpdate.offersIntern.monthlySalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: offerToUpdate.offersIntern.monthlySalary.currency,
|
||||
value: offerToUpdate.offersIntern.monthlySalary.value,
|
||||
},
|
||||
@ -916,7 +1016,7 @@ export const offersProfileRouter = createRouter()
|
||||
});
|
||||
}
|
||||
|
||||
if (offerToUpdate.offersFullTime?.totalCompensation) {
|
||||
if (offerToUpdate.offersFullTime?.totalCompensation != null) {
|
||||
await ctx.prisma.offersFullTime.update({
|
||||
data: {
|
||||
level: offerToUpdate.offersFullTime.level ?? undefined,
|
||||
@ -927,9 +1027,15 @@ export const offersProfileRouter = createRouter()
|
||||
id: offerToUpdate.offersFullTime.id,
|
||||
},
|
||||
});
|
||||
if (offerToUpdate.offersFullTime.baseSalary) {
|
||||
if (offerToUpdate.offersFullTime.baseSalary != null) {
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.baseSalary.value,
|
||||
offerToUpdate.offersFullTime.baseSalary.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: offerToUpdate.offersFullTime.baseSalary.currency,
|
||||
value: offerToUpdate.offersFullTime.baseSalary.value,
|
||||
},
|
||||
@ -941,6 +1047,12 @@ export const offersProfileRouter = createRouter()
|
||||
if (offerToUpdate.offersFullTime.bonus) {
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.bonus.value,
|
||||
offerToUpdate.offersFullTime.bonus.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: offerToUpdate.offersFullTime.bonus.currency,
|
||||
value: offerToUpdate.offersFullTime.bonus.value,
|
||||
},
|
||||
@ -952,6 +1064,12 @@ export const offersProfileRouter = createRouter()
|
||||
if (offerToUpdate.offersFullTime.stocks) {
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.stocks.value,
|
||||
offerToUpdate.offersFullTime.stocks.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency: offerToUpdate.offersFullTime.stocks.currency,
|
||||
value: offerToUpdate.offersFullTime.stocks.value,
|
||||
},
|
||||
@ -962,6 +1080,12 @@ export const offersProfileRouter = createRouter()
|
||||
}
|
||||
await ctx.prisma.offersCurrency.update({
|
||||
data: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.totalCompensation.value,
|
||||
offerToUpdate.offersFullTime.totalCompensation.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
offerToUpdate.offersFullTime.totalCompensation.currency,
|
||||
value: offerToUpdate.offersFullTime.totalCompensation.value,
|
||||
@ -974,12 +1098,12 @@ export const offersProfileRouter = createRouter()
|
||||
} else {
|
||||
// Create new offer
|
||||
if (
|
||||
offerToUpdate.jobType === 'INTERN' &&
|
||||
offerToUpdate.jobType === JobType.INTERN &&
|
||||
offerToUpdate.offersIntern &&
|
||||
offerToUpdate.offersIntern.internshipCycle &&
|
||||
offerToUpdate.offersIntern.monthlySalary?.currency &&
|
||||
offerToUpdate.offersIntern.monthlySalary.value &&
|
||||
offerToUpdate.offersIntern.startYear
|
||||
offerToUpdate.offersIntern.internshipCycle != null &&
|
||||
offerToUpdate.offersIntern.monthlySalary?.currency != null &&
|
||||
offerToUpdate.offersIntern.monthlySalary?.value != null &&
|
||||
offerToUpdate.offersIntern.startYear != null
|
||||
) {
|
||||
await ctx.prisma.offersProfile.update({
|
||||
data: {
|
||||
@ -1001,11 +1125,18 @@ export const offersProfileRouter = createRouter()
|
||||
offerToUpdate.offersIntern.internshipCycle,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersIntern.monthlySalary.value,
|
||||
offerToUpdate.offersIntern.monthlySalary
|
||||
.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
offerToUpdate.offersIntern.monthlySalary
|
||||
?.currency,
|
||||
.currency,
|
||||
value:
|
||||
offerToUpdate.offersIntern.monthlySalary?.value,
|
||||
offerToUpdate.offersIntern.monthlySalary.value,
|
||||
},
|
||||
},
|
||||
specialization:
|
||||
@ -1023,17 +1154,18 @@ export const offersProfileRouter = createRouter()
|
||||
});
|
||||
}
|
||||
if (
|
||||
offerToUpdate.jobType === 'FULLTIME' &&
|
||||
offerToUpdate.jobType === JobType.FULLTIME &&
|
||||
offerToUpdate.offersFullTime &&
|
||||
offerToUpdate.offersFullTime.baseSalary?.currency &&
|
||||
offerToUpdate.offersFullTime.baseSalary?.value &&
|
||||
offerToUpdate.offersFullTime.bonus?.currency &&
|
||||
offerToUpdate.offersFullTime.bonus?.value &&
|
||||
offerToUpdate.offersFullTime.stocks?.currency &&
|
||||
offerToUpdate.offersFullTime.stocks?.value &&
|
||||
offerToUpdate.offersFullTime.totalCompensation?.currency &&
|
||||
offerToUpdate.offersFullTime.totalCompensation?.value &&
|
||||
offerToUpdate.offersFullTime.level
|
||||
offerToUpdate.offersFullTime.baseSalary?.currency != null &&
|
||||
offerToUpdate.offersFullTime.baseSalary?.value != null &&
|
||||
offerToUpdate.offersFullTime.bonus?.currency != null &&
|
||||
offerToUpdate.offersFullTime.bonus?.value != null &&
|
||||
offerToUpdate.offersFullTime.stocks?.currency != null &&
|
||||
offerToUpdate.offersFullTime.stocks?.value != null &&
|
||||
offerToUpdate.offersFullTime.totalCompensation?.currency !=
|
||||
null &&
|
||||
offerToUpdate.offersFullTime.totalCompensation?.value != null &&
|
||||
offerToUpdate.offersFullTime.level != null
|
||||
) {
|
||||
await ctx.prisma.offersProfile.update({
|
||||
data: {
|
||||
@ -1053,18 +1185,31 @@ export const offersProfileRouter = createRouter()
|
||||
create: {
|
||||
baseSalary: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.baseSalary.value,
|
||||
offerToUpdate.offersFullTime.baseSalary
|
||||
.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
offerToUpdate.offersFullTime.baseSalary
|
||||
?.currency,
|
||||
.currency,
|
||||
value:
|
||||
offerToUpdate.offersFullTime.baseSalary?.value,
|
||||
offerToUpdate.offersFullTime.baseSalary.value,
|
||||
},
|
||||
},
|
||||
bonus: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.bonus.value,
|
||||
offerToUpdate.offersFullTime.bonus.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
offerToUpdate.offersFullTime.bonus?.currency,
|
||||
value: offerToUpdate.offersFullTime.bonus?.value,
|
||||
offerToUpdate.offersFullTime.bonus.currency,
|
||||
value: offerToUpdate.offersFullTime.bonus.value,
|
||||
},
|
||||
},
|
||||
level: offerToUpdate.offersFullTime.level,
|
||||
@ -1072,20 +1217,34 @@ export const offersProfileRouter = createRouter()
|
||||
offerToUpdate.offersFullTime.specialization,
|
||||
stocks: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.stocks.value,
|
||||
offerToUpdate.offersFullTime.stocks.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
offerToUpdate.offersFullTime.stocks?.currency,
|
||||
value: offerToUpdate.offersFullTime.stocks?.value,
|
||||
offerToUpdate.offersFullTime.stocks.currency,
|
||||
value: offerToUpdate.offersFullTime.stocks.value,
|
||||
},
|
||||
},
|
||||
title: offerToUpdate.offersFullTime.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
baseCurrency: baseCurrencyString,
|
||||
baseValue: await convert(
|
||||
offerToUpdate.offersFullTime.totalCompensation
|
||||
.value,
|
||||
offerToUpdate.offersFullTime.totalCompensation
|
||||
.currency,
|
||||
baseCurrencyString,
|
||||
),
|
||||
currency:
|
||||
offerToUpdate.offersFullTime.totalCompensation
|
||||
?.currency,
|
||||
.currency,
|
||||
value:
|
||||
offerToUpdate.offersFullTime.totalCompensation
|
||||
?.value,
|
||||
.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1102,46 +1261,6 @@ export const offersProfileRouter = createRouter()
|
||||
}
|
||||
|
||||
const result = await ctx.prisma.offersProfile.findFirst({
|
||||
include: {
|
||||
background: {
|
||||
include: {
|
||||
educations: true,
|
||||
experiences: {
|
||||
include: {
|
||||
company: true,
|
||||
monthlySalary: true,
|
||||
totalCompensation: true,
|
||||
},
|
||||
},
|
||||
specificYoes: true,
|
||||
},
|
||||
},
|
||||
discussion: {
|
||||
include: {
|
||||
replies: true,
|
||||
replyingTo: true,
|
||||
user: true,
|
||||
},
|
||||
},
|
||||
offers: {
|
||||
include: {
|
||||
company: true,
|
||||
offersFullTime: {
|
||||
include: {
|
||||
baseSalary: true,
|
||||
bonus: true,
|
||||
stocks: true,
|
||||
totalCompensation: true,
|
||||
},
|
||||
},
|
||||
offersIntern: {
|
||||
include: {
|
||||
monthlySalary: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
where: {
|
||||
id: input.id,
|
||||
},
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
} from '~/mappers/offers-mappers';
|
||||
import { convert } from '~/utils/offers/currency/currency-exchange';
|
||||
import { Currency } from '~/utils/offers/currency/CurrencyEnum';
|
||||
import { createValidationRegex } from '~/utils/offers/zodRegex';
|
||||
|
||||
import { createRouter } from '../context';
|
||||
|
||||
@ -23,14 +24,6 @@ const sortingKeysMap = {
|
||||
totalYoe: 'totalYoe',
|
||||
};
|
||||
|
||||
const createSortByValidationRegex = () => {
|
||||
const startsWithPlusOrMinusOnly = '^[+-]{1}';
|
||||
const sortingKeysRegex = Object.entries(sortingKeysMap)
|
||||
.map((entry) => entry[0])
|
||||
.join('|');
|
||||
return new RegExp(startsWithPlusOrMinusOnly + '(' + sortingKeysRegex + ')');
|
||||
};
|
||||
|
||||
const yoeCategoryMap: Record<number, string> = {
|
||||
0: 'Internship',
|
||||
1: 'Fresh Grad',
|
||||
@ -59,7 +52,10 @@ export const offersRouter = createRouter().query('list', {
|
||||
offset: z.number().nonnegative(),
|
||||
salaryMax: z.number().nonnegative().nullish(),
|
||||
salaryMin: z.number().nonnegative().nullish(),
|
||||
sortBy: z.string().regex(createSortByValidationRegex()).nullish(),
|
||||
sortBy: z
|
||||
.string()
|
||||
.regex(createValidationRegex(Object.keys(sortingKeysMap), '[+-]{1}'))
|
||||
.nullish(),
|
||||
title: z.string().nullish(),
|
||||
yoeCategory: z.number().min(0).max(3),
|
||||
yoeMax: z.number().max(100).nullish(),
|
||||
@ -70,8 +66,6 @@ export const offersRouter = createRouter().query('list', {
|
||||
const yoeMin = input.yoeMin ? input.yoeMin : yoeRange?.minYoe;
|
||||
const yoeMax = input.yoeMax ? input.yoeMax : yoeRange?.maxYoe;
|
||||
|
||||
// Const orderBy = getSortingOrderAndKey(input.sortBy, input.yoeCategory);
|
||||
|
||||
if (!input.sortBy) {
|
||||
input.sortBy = '-' + sortingKeysMap.monthYearReceived;
|
||||
}
|
||||
@ -338,112 +332,6 @@ export const offersRouter = createRouter().query('list', {
|
||||
);
|
||||
}
|
||||
|
||||
// SORTING
|
||||
// data = data.sort((offer1, offer2) => {
|
||||
// const defaultReturn =
|
||||
// offer2.monthYearReceived.getTime() - offer1.monthYearReceived.getTime();
|
||||
|
||||
// if (!input.sortBy) {
|
||||
// return defaultReturn;
|
||||
// }
|
||||
|
||||
// const order = input.sortBy.charAt(0);
|
||||
// const sortingKey = input.sortBy.substring(1);
|
||||
|
||||
// if (order === ascOrder) {
|
||||
// return (() => {
|
||||
// if (sortingKey === 'monthYearReceived') {
|
||||
// return (
|
||||
// offer1.monthYearReceived.getTime() -
|
||||
// offer2.monthYearReceived.getTime()
|
||||
// );
|
||||
// }
|
||||
|
||||
// if (sortingKey === 'totalCompensation') {
|
||||
// const salary1 = offer1.offersFullTime?.totalCompensation.value
|
||||
// ? offer1.offersFullTime?.totalCompensation.value
|
||||
// : offer1.offersIntern?.monthlySalary.value;
|
||||
|
||||
// const salary2 = offer2.offersFullTime?.totalCompensation.value
|
||||
// ? offer2.offersFullTime?.totalCompensation.value
|
||||
// : offer2.offersIntern?.monthlySalary.value;
|
||||
|
||||
// if (salary1 == null || salary2 == null) {
|
||||
// throw new TRPCError({
|
||||
// code: 'NOT_FOUND',
|
||||
// message: 'Total Compensation or Salary not found',
|
||||
// });
|
||||
// }
|
||||
|
||||
// return salary1 - salary2;
|
||||
// }
|
||||
|
||||
// if (sortingKey === 'totalYoe') {
|
||||
// const yoe1 = offer1.profile.background?.totalYoe;
|
||||
// const yoe2 = offer2.profile.background?.totalYoe;
|
||||
|
||||
// if (yoe1 == null || yoe2 == null) {
|
||||
// throw new TRPCError({
|
||||
// code: 'NOT_FOUND',
|
||||
// message: 'Total years of experience not found',
|
||||
// });
|
||||
// }
|
||||
|
||||
// return yoe1 - yoe2;
|
||||
// }
|
||||
|
||||
// return defaultReturn;
|
||||
// })();
|
||||
// }
|
||||
|
||||
// if (order === descOrder) {
|
||||
// return (() => {
|
||||
// if (sortingKey === 'monthYearReceived') {
|
||||
// return (
|
||||
// offer2.monthYearReceived.getTime() -
|
||||
// offer1.monthYearReceived.getTime()
|
||||
// );
|
||||
// }
|
||||
|
||||
// if (sortingKey === 'totalCompensation') {
|
||||
// const salary1 = offer1.offersFullTime?.totalCompensation.value
|
||||
// ? offer1.offersFullTime?.totalCompensation.value
|
||||
// : offer1.offersIntern?.monthlySalary.value;
|
||||
|
||||
// const salary2 = offer2.offersFullTime?.totalCompensation.value
|
||||
// ? offer2.offersFullTime?.totalCompensation.value
|
||||
// : offer2.offersIntern?.monthlySalary.value;
|
||||
|
||||
// if (salary1 == null || salary2 == null) {
|
||||
// throw new TRPCError({
|
||||
// code: 'NOT_FOUND',
|
||||
// message: 'Total Compensation or Salary not found',
|
||||
// });
|
||||
// }
|
||||
|
||||
// return salary2 - salary1;
|
||||
// }
|
||||
|
||||
// if (sortingKey === 'totalYoe') {
|
||||
// const yoe1 = offer1.profile.background?.totalYoe;
|
||||
// const yoe2 = offer2.profile.background?.totalYoe;
|
||||
|
||||
// if (yoe1 == null || yoe2 == null) {
|
||||
// throw new TRPCError({
|
||||
// code: 'NOT_FOUND',
|
||||
// message: 'Total years of experience not found',
|
||||
// });
|
||||
// }
|
||||
|
||||
// return yoe2 - yoe1;
|
||||
// }
|
||||
|
||||
// return defaultReturn;
|
||||
// })();
|
||||
// }
|
||||
// return defaultReturn;
|
||||
// });
|
||||
|
||||
const startRecordIndex: number = input.limit * input.offset;
|
||||
const endRecordIndex: number =
|
||||
startRecordIndex + input.limit <= data.length
|
||||
|
@ -6,7 +6,11 @@ export const convert = async (
|
||||
) => {
|
||||
fromCurrency = fromCurrency.trim().toLowerCase();
|
||||
toCurrency = toCurrency.trim().toLowerCase();
|
||||
const url = ['https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies', fromCurrency, toCurrency].join('/');
|
||||
const url = [
|
||||
'https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies',
|
||||
fromCurrency,
|
||||
toCurrency,
|
||||
].join('/');
|
||||
|
||||
return await fetch(url + '.json')
|
||||
.then((res) => res.json())
|
||||
|
@ -1,5 +1,9 @@
|
||||
import type { Money } from '~/components/offers/types';
|
||||
|
||||
import { Currency } from './CurrencyEnum';
|
||||
|
||||
export const baseCurrencyString = Currency.USD.toString();
|
||||
|
||||
export function convertMoneyToString({ currency, value }: Money) {
|
||||
if (!value) {
|
||||
return '-';
|
||||
|
8
apps/portal/src/utils/offers/zodRegex.ts
Normal file
8
apps/portal/src/utils/offers/zodRegex.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export const createValidationRegex = (
|
||||
keywordArray: Array<string>,
|
||||
prepend: string | null | undefined,
|
||||
) => {
|
||||
const sortingKeysRegex = keywordArray.join('|');
|
||||
prepend = prepend != null ? prepend : '';
|
||||
return new RegExp('^' + prepend + '(' + sortingKeysRegex + ')$');
|
||||
};
|
Reference in New Issue
Block a user