Merge branch 'sprint1' of http://git.wdipl.com/Mayank.Mishra/MinglarBackendNestJS into paritosh-main1
This commit is contained in:
@@ -53,6 +53,12 @@ export async function generateActivityRefNumber(tx: any) {
|
||||
return `ACT-${String(nextId).padStart(6, '0')}`;;
|
||||
}
|
||||
|
||||
function round2(value: number) {
|
||||
return Math.round(value * 100) / 100;
|
||||
}
|
||||
|
||||
const bucket = config.aws.bucketName;
|
||||
|
||||
@Injectable()
|
||||
export class HostService {
|
||||
constructor(private prisma: PrismaService) { }
|
||||
@@ -140,8 +146,6 @@ export class HostService {
|
||||
return { stepper: STEPPER.NOT_SUBMITTED } as any;
|
||||
}
|
||||
|
||||
const bucket = config.aws.bucketName;
|
||||
|
||||
if (host.HostDocuments?.length) {
|
||||
|
||||
for (const doc of host.HostDocuments) {
|
||||
@@ -394,7 +398,7 @@ export class HostService {
|
||||
}
|
||||
|
||||
async getPQQQuestionDetail(question_xid: number, activity_xid: number) {
|
||||
return await this.prisma.activityPQQheader.findFirst({
|
||||
const detailsOfQuestion = await this.prisma.activityPQQheader.findFirst({
|
||||
where: {
|
||||
activityXid: activity_xid,
|
||||
pqqQuestionXid: question_xid,
|
||||
@@ -403,10 +407,42 @@ export class HostService {
|
||||
select: {
|
||||
pqqQuestionXid: true,
|
||||
pqqAnswerXid: true,
|
||||
ActivityPQQSupportings: true,
|
||||
ActivityPQQSuggestions: true,
|
||||
ActivityPQQSupportings: {
|
||||
select: {
|
||||
id: true,
|
||||
activityPqqHeaderXid: true,
|
||||
mediaFileName: true,
|
||||
mediaType: true
|
||||
}
|
||||
},
|
||||
ActivityPQQSuggestions: {
|
||||
where: { isActive: true, isReviewed: false },
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
comments: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (detailsOfQuestion.ActivityPQQSupportings?.length) {
|
||||
|
||||
for (const doc of detailsOfQuestion.ActivityPQQSupportings) {
|
||||
if (doc.mediaFileName) {
|
||||
const filePath = doc.mediaFileName;
|
||||
|
||||
// If full URL is saved, extract only key
|
||||
const key = filePath.startsWith('http')
|
||||
? filePath.split('.com/')[1]
|
||||
: filePath;
|
||||
|
||||
(doc as any).presignedUrl = await getPresignedUrl(bucket, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return detailsOfQuestion;
|
||||
}
|
||||
|
||||
async getLatestQuestionDetailsPQQ(activity_xid: number) {
|
||||
@@ -431,92 +467,201 @@ export class HostService {
|
||||
}
|
||||
|
||||
async addOrUpdateCompanyDetails(
|
||||
user_xid: number,
|
||||
companyData: HostCompanyDetailsInput,
|
||||
documents: HostDocumentInput[],
|
||||
parentCompanyData?: any | null,
|
||||
parentDocuments?: HostDocumentInput[],
|
||||
isDraft: boolean = false,
|
||||
) {
|
||||
return await this.prisma.$transaction(async (tx) => {
|
||||
// Check if host already has a company
|
||||
const existingHostCompany = await tx.hostHeader.findFirst({
|
||||
where: { userXid: user_xid },
|
||||
include: { hostParent: true },
|
||||
});
|
||||
user_xid: number,
|
||||
companyData: HostCompanyDetailsInput,
|
||||
documents: HostDocumentInput[],
|
||||
parentCompanyData?: any | null,
|
||||
parentDocuments?: HostDocumentInput[],
|
||||
isDraft: boolean = false,
|
||||
) {
|
||||
return await this.prisma.$transaction(async (tx) => {
|
||||
// Check if host already has a company
|
||||
const existingHostCompany = await tx.hostHeader.findFirst({
|
||||
where: { userXid: user_xid },
|
||||
include: { hostParent: true },
|
||||
});
|
||||
|
||||
let hostStatusInternal;
|
||||
let hostStatusDisplay;
|
||||
let minglarStatusInternal;
|
||||
let minglarStatusDisplay;
|
||||
let hostStatusInternal;
|
||||
let hostStatusDisplay;
|
||||
let minglarStatusInternal;
|
||||
let minglarStatusDisplay;
|
||||
|
||||
if (existingHostCompany) {
|
||||
hostStatusInternal = existingHostCompany.hostStatusInternal;
|
||||
hostStatusDisplay = existingHostCompany.hostStatusDisplay;
|
||||
minglarStatusInternal = existingHostCompany.adminStatusInternal;
|
||||
minglarStatusDisplay = existingHostCompany.adminStatusDisplay;
|
||||
}
|
||||
|
||||
// CASE 1: Host was asked to update AND is submitting final
|
||||
if (
|
||||
existingHostCompany &&
|
||||
existingHostCompany.hostStatusInternal === HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
|
||||
!isDraft
|
||||
) {
|
||||
hostStatusInternal = HOST_STATUS_INTERNAL.HOST_SUBMITTED;
|
||||
hostStatusDisplay = HOST_STATUS_DISPLAY.UNDER_REVIEW;
|
||||
|
||||
minglarStatusInternal = MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW;
|
||||
minglarStatusDisplay = MINGLAR_STATUS_DISPLAY.TO_REVIEW;
|
||||
}
|
||||
// CASE 2: Host was asked to update BUT saving draft
|
||||
else if (
|
||||
existingHostCompany &&
|
||||
existingHostCompany.hostStatusInternal === HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
|
||||
isDraft
|
||||
) {
|
||||
// keep original
|
||||
hostStatusInternal = existingHostCompany.hostStatusInternal;
|
||||
hostStatusDisplay = existingHostCompany.hostStatusDisplay;
|
||||
minglarStatusInternal = existingHostCompany.adminStatusInternal;
|
||||
minglarStatusDisplay = existingHostCompany.adminStatusDisplay;
|
||||
}
|
||||
// CASE 3: Normal create or update
|
||||
else {
|
||||
hostStatusInternal = isDraft
|
||||
? HOST_STATUS_INTERNAL.DRAFT
|
||||
: HOST_STATUS_INTERNAL.HOST_SUBMITTED;
|
||||
|
||||
hostStatusDisplay = isDraft
|
||||
? HOST_STATUS_DISPLAY.DRAFT
|
||||
: HOST_STATUS_DISPLAY.UNDER_REVIEW;
|
||||
|
||||
minglarStatusInternal = isDraft
|
||||
? MINGLAR_STATUS_INTERNAL.DRAFT
|
||||
: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW;
|
||||
|
||||
minglarStatusDisplay = isDraft
|
||||
? MINGLAR_STATUS_DISPLAY.DRAFT
|
||||
: MINGLAR_STATUS_DISPLAY.NEW;
|
||||
}
|
||||
|
||||
const stepper = isDraft ? STEPPER.NOT_SUBMITTED : STEPPER.UNDER_REVIEW;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// CREATE FLOW
|
||||
// -------------------------------------------------------
|
||||
if (!existingHostCompany) {
|
||||
if (!isDraft) {
|
||||
const existingByPan = await tx.hostHeader.findFirst({
|
||||
where: { panNumber: companyData.panNumber },
|
||||
});
|
||||
if (existingByPan)
|
||||
throw new ApiError(400, 'Company already exists with this pan/bin number');
|
||||
if (existingHostCompany) {
|
||||
hostStatusInternal = existingHostCompany.hostStatusInternal;
|
||||
hostStatusDisplay = existingHostCompany.hostStatusDisplay;
|
||||
minglarStatusInternal = existingHostCompany.adminStatusInternal;
|
||||
minglarStatusDisplay = existingHostCompany.adminStatusDisplay;
|
||||
}
|
||||
|
||||
const createdHost = await tx.hostHeader.create({
|
||||
// CASE 1: Host was asked to update AND is submitting final
|
||||
if (
|
||||
existingHostCompany &&
|
||||
existingHostCompany.hostStatusInternal === HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
|
||||
!isDraft
|
||||
) {
|
||||
hostStatusInternal = HOST_STATUS_INTERNAL.HOST_SUBMITTED;
|
||||
hostStatusDisplay = HOST_STATUS_DISPLAY.UNDER_REVIEW;
|
||||
|
||||
minglarStatusInternal = MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW;
|
||||
minglarStatusDisplay = MINGLAR_STATUS_DISPLAY.TO_REVIEW;
|
||||
}
|
||||
// CASE 2: Host was asked to update BUT saving draft
|
||||
else if (
|
||||
existingHostCompany &&
|
||||
existingHostCompany.hostStatusInternal === HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
|
||||
isDraft
|
||||
) {
|
||||
// keep original
|
||||
hostStatusInternal = existingHostCompany.hostStatusInternal;
|
||||
hostStatusDisplay = existingHostCompany.hostStatusDisplay;
|
||||
minglarStatusInternal = existingHostCompany.adminStatusInternal;
|
||||
minglarStatusDisplay = existingHostCompany.adminStatusDisplay;
|
||||
}
|
||||
// CASE 3: Normal create or update
|
||||
else {
|
||||
hostStatusInternal = isDraft
|
||||
? HOST_STATUS_INTERNAL.DRAFT
|
||||
: HOST_STATUS_INTERNAL.HOST_SUBMITTED;
|
||||
|
||||
hostStatusDisplay = isDraft
|
||||
? HOST_STATUS_DISPLAY.DRAFT
|
||||
: HOST_STATUS_DISPLAY.UNDER_REVIEW;
|
||||
|
||||
minglarStatusInternal = isDraft
|
||||
? MINGLAR_STATUS_INTERNAL.DRAFT
|
||||
: MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW;
|
||||
|
||||
minglarStatusDisplay = isDraft
|
||||
? MINGLAR_STATUS_DISPLAY.DRAFT
|
||||
: MINGLAR_STATUS_DISPLAY.NEW;
|
||||
}
|
||||
|
||||
const stepper = isDraft ? STEPPER.NOT_SUBMITTED : STEPPER.UNDER_REVIEW;
|
||||
|
||||
// -------------------------------------------------------
|
||||
// CREATE FLOW
|
||||
// -------------------------------------------------------
|
||||
if (!existingHostCompany) {
|
||||
if (!isDraft) {
|
||||
const existingByPan = await tx.hostHeader.findFirst({
|
||||
where: { panNumber: companyData.panNumber },
|
||||
});
|
||||
if (existingByPan)
|
||||
throw new ApiError(400, 'Company already exists with this pan/bin number');
|
||||
}
|
||||
|
||||
const createdHost = await tx.hostHeader.create({
|
||||
data: {
|
||||
user: { connect: { id: user_xid } },
|
||||
companyName: companyData.companyName,
|
||||
address1: companyData.address1,
|
||||
address2: companyData.address2,
|
||||
cities: companyData.cityXid ? { connect: { id: companyData.cityXid } } : undefined,
|
||||
states: companyData.stateXid ? { connect: { id: companyData.stateXid } } : undefined,
|
||||
countries: companyData.countryXid ? { connect: { id: companyData.countryXid } } : undefined,
|
||||
pinCode: companyData.pinCode,
|
||||
logoPath: companyData.logoPath || null,
|
||||
isSubsidairy: companyData.isSubsidairy,
|
||||
registrationNumber: companyData.registrationNumber,
|
||||
panNumber: companyData.panNumber,
|
||||
gstNumber: companyData.gstNumber || null,
|
||||
formationDate: companyData.formationDate
|
||||
? new Date(companyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: companyData.companyTypeXid
|
||||
? { connect: { id: companyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: companyData.websiteUrl || null,
|
||||
instagramUrl: companyData.instagramUrl || null,
|
||||
facebookUrl: companyData.facebookUrl || null,
|
||||
linkedinUrl: companyData.linkedinUrl || null,
|
||||
twitterUrl: companyData.twitterUrl || null,
|
||||
stepper,
|
||||
hostStatusInternal,
|
||||
hostStatusDisplay,
|
||||
adminStatusInternal: minglarStatusInternal,
|
||||
adminStatusDisplay: minglarStatusDisplay,
|
||||
},
|
||||
});
|
||||
|
||||
// host documents
|
||||
if (documents?.length) {
|
||||
const docsData = documents.map((doc) => ({
|
||||
hostXid: createdHost.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
}));
|
||||
await tx.hostDocuments.createMany({ data: docsData });
|
||||
}
|
||||
|
||||
// parent create
|
||||
if (companyData.isSubsidairy && parentCompanyData) {
|
||||
const createdParent = await tx.hostParent.create({
|
||||
data: {
|
||||
host: { connect: { id: createdHost.id } },
|
||||
companyName: parentCompanyData.companyName,
|
||||
address1: parentCompanyData.address1 || null,
|
||||
address2: parentCompanyData.address2 || null,
|
||||
cities: parentCompanyData.cityXid
|
||||
? { connect: { id: parentCompanyData.cityXid } }
|
||||
: undefined,
|
||||
states: parentCompanyData.stateXid
|
||||
? { connect: { id: parentCompanyData.stateXid } }
|
||||
: undefined,
|
||||
countries: parentCompanyData.countryXid
|
||||
? { connect: { id: parentCompanyData.countryXid } }
|
||||
: undefined,
|
||||
pinCode: parentCompanyData.pinCode || null,
|
||||
logoPath: parentCompanyData.logoPath || null,
|
||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||
panNumber: parentCompanyData.panNumber || null,
|
||||
gstNumber: parentCompanyData.gstNumber || null,
|
||||
formationDate: parentCompanyData.formationDate
|
||||
? new Date(parentCompanyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: parentCompanyData.companyTypeXid
|
||||
? { connect: { id: parentCompanyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: parentCompanyData.websiteUrl || null,
|
||||
instagramUrl: parentCompanyData.instagramUrl || null,
|
||||
facebookUrl: parentCompanyData.facebookUrl || null,
|
||||
linkedinUrl: parentCompanyData.linkedinUrl || null,
|
||||
twitterUrl: parentCompanyData.twitterUrl || null,
|
||||
},
|
||||
});
|
||||
|
||||
// parent docs
|
||||
if (parentDocuments?.length) {
|
||||
const parentDocsData = parentDocuments.map((doc) => ({
|
||||
hostParentXid: createdParent.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
}));
|
||||
await tx.hostParenetDocuments.createMany({ data: parentDocsData });
|
||||
}
|
||||
}
|
||||
|
||||
// ⭐ FIX — TRACK USING createdHost (no null risk)
|
||||
await tx.hostTrack.create({
|
||||
data: {
|
||||
hostXid: createdHost.id,
|
||||
updatedByRole: ROLE_NAME.HOST,
|
||||
updatedByXid: user_xid,
|
||||
trackStatus: createdHost.hostStatusInternal,
|
||||
},
|
||||
});
|
||||
|
||||
return createdHost;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// UPDATE FLOW
|
||||
// -------------------------------------------------------
|
||||
const updatedHost = await tx.hostHeader.update({
|
||||
where: { id: existingHostCompany.id },
|
||||
data: {
|
||||
user: { connect: { id: user_xid } },
|
||||
companyName: companyData.companyName,
|
||||
address1: companyData.address1,
|
||||
address2: companyData.address2,
|
||||
@@ -548,191 +693,28 @@ export class HostService {
|
||||
},
|
||||
});
|
||||
|
||||
// host documents
|
||||
// documents UPSERT
|
||||
if (documents?.length) {
|
||||
const docsData = documents.map((doc) => ({
|
||||
hostXid: createdHost.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
}));
|
||||
await tx.hostDocuments.createMany({ data: docsData });
|
||||
}
|
||||
|
||||
// parent create
|
||||
if (companyData.isSubsidairy && parentCompanyData) {
|
||||
const createdParent = await tx.hostParent.create({
|
||||
data: {
|
||||
host: { connect: { id: createdHost.id } },
|
||||
companyName: parentCompanyData.companyName,
|
||||
address1: parentCompanyData.address1 || null,
|
||||
address2: parentCompanyData.address2 || null,
|
||||
cities: parentCompanyData.cityXid
|
||||
? { connect: { id: parentCompanyData.cityXid } }
|
||||
: undefined,
|
||||
states: parentCompanyData.stateXid
|
||||
? { connect: { id: parentCompanyData.stateXid } }
|
||||
: undefined,
|
||||
countries: parentCompanyData.countryXid
|
||||
? { connect: { id: parentCompanyData.countryXid } }
|
||||
: undefined,
|
||||
pinCode: parentCompanyData.pinCode || null,
|
||||
logoPath: parentCompanyData.logoPath || null,
|
||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||
panNumber: parentCompanyData.panNumber || null,
|
||||
gstNumber: parentCompanyData.gstNumber || null,
|
||||
formationDate: parentCompanyData.formationDate
|
||||
? new Date(parentCompanyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: parentCompanyData.companyTypeXid
|
||||
? { connect: { id: parentCompanyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: parentCompanyData.websiteUrl || null,
|
||||
instagramUrl: parentCompanyData.instagramUrl || null,
|
||||
facebookUrl: parentCompanyData.facebookUrl || null,
|
||||
linkedinUrl: parentCompanyData.linkedinUrl || null,
|
||||
twitterUrl: parentCompanyData.twitterUrl || null,
|
||||
},
|
||||
});
|
||||
|
||||
// parent docs
|
||||
if (parentDocuments?.length) {
|
||||
const parentDocsData = parentDocuments.map((doc) => ({
|
||||
hostParentXid: createdParent.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
}));
|
||||
await tx.hostParenetDocuments.createMany({ data: parentDocsData });
|
||||
}
|
||||
}
|
||||
|
||||
// ⭐ FIX — TRACK USING createdHost (no null risk)
|
||||
await tx.hostTrack.create({
|
||||
data: {
|
||||
hostXid: createdHost.id,
|
||||
updatedByRole: ROLE_NAME.HOST,
|
||||
updatedByXid: user_xid,
|
||||
trackStatus: createdHost.hostStatusInternal,
|
||||
},
|
||||
});
|
||||
|
||||
return createdHost;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// UPDATE FLOW
|
||||
// -------------------------------------------------------
|
||||
const updatedHost = await tx.hostHeader.update({
|
||||
where: { id: existingHostCompany.id },
|
||||
data: {
|
||||
companyName: companyData.companyName,
|
||||
address1: companyData.address1,
|
||||
address2: companyData.address2,
|
||||
cities: companyData.cityXid ? { connect: { id: companyData.cityXid } } : undefined,
|
||||
states: companyData.stateXid ? { connect: { id: companyData.stateXid } } : undefined,
|
||||
countries: companyData.countryXid ? { connect: { id: companyData.countryXid } } : undefined,
|
||||
pinCode: companyData.pinCode,
|
||||
logoPath: companyData.logoPath || null,
|
||||
isSubsidairy: companyData.isSubsidairy,
|
||||
registrationNumber: companyData.registrationNumber,
|
||||
panNumber: companyData.panNumber,
|
||||
gstNumber: companyData.gstNumber || null,
|
||||
formationDate: companyData.formationDate
|
||||
? new Date(companyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: companyData.companyTypeXid
|
||||
? { connect: { id: companyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: companyData.websiteUrl || null,
|
||||
instagramUrl: companyData.instagramUrl || null,
|
||||
facebookUrl: companyData.facebookUrl || null,
|
||||
linkedinUrl: companyData.linkedinUrl || null,
|
||||
twitterUrl: companyData.twitterUrl || null,
|
||||
stepper,
|
||||
hostStatusInternal,
|
||||
hostStatusDisplay,
|
||||
adminStatusInternal: minglarStatusInternal,
|
||||
adminStatusDisplay: minglarStatusDisplay,
|
||||
},
|
||||
});
|
||||
|
||||
// documents UPSERT
|
||||
if (documents?.length) {
|
||||
for (const doc of documents) {
|
||||
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: doc.documentName || existingDoc.documentName,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
await tx.hostDocuments.create({
|
||||
data: {
|
||||
for (const doc of documents) {
|
||||
const existingDoc = await tx.hostDocuments.findFirst({
|
||||
where: {
|
||||
hostXid: updatedHost.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parent logic untouched
|
||||
if (companyData.isSubsidairy) {
|
||||
const parentRecords = existingHostCompany.hostParent;
|
||||
const parentRecord = Array.isArray(parentRecords) ? parentRecords[0] : parentRecords;
|
||||
|
||||
if (!parentRecord) {
|
||||
const createdParent = await tx.hostParent.create({
|
||||
data: {
|
||||
host: { connect: { id: updatedHost.id } },
|
||||
companyName: parentCompanyData.companyName,
|
||||
address1: parentCompanyData.address1 || null,
|
||||
address2: parentCompanyData.address2 || null,
|
||||
cities: parentCompanyData.cityXid
|
||||
? { connect: { id: parentCompanyData.cityXid } }
|
||||
: undefined,
|
||||
states: parentCompanyData.stateXid
|
||||
? { connect: { id: parentCompanyData.stateXid } }
|
||||
: undefined,
|
||||
countries: parentCompanyData.countryXid
|
||||
? { connect: { id: parentCompanyData.countryXid } }
|
||||
: undefined,
|
||||
pinCode: parentCompanyData.pinCode || null,
|
||||
logoPath: parentCompanyData.logoPath || null,
|
||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||
panNumber: parentCompanyData.panNumber || null,
|
||||
gstNumber: parentCompanyData.gstNumber || null,
|
||||
formationDate: parentCompanyData.formationDate
|
||||
? new Date(parentCompanyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: parentCompanyData.companyTypeXid
|
||||
? { connect: { id: parentCompanyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: parentCompanyData.websiteUrl || null,
|
||||
instagramUrl: parentCompanyData.instagramUrl || null,
|
||||
facebookUrl: parentCompanyData.facebookUrl || null,
|
||||
linkedinUrl: parentCompanyData.linkedinUrl || null,
|
||||
twitterUrl: parentCompanyData.twitterUrl || null,
|
||||
},
|
||||
});
|
||||
|
||||
if (parentDocuments?.length) {
|
||||
for (const doc of parentDocuments) {
|
||||
await tx.hostParenetDocuments.create({
|
||||
if (existingDoc) {
|
||||
await tx.hostDocuments.update({
|
||||
where: { id: existingDoc.id },
|
||||
data: {
|
||||
hostParentXid: createdParent.id,
|
||||
filePath: doc.filePath,
|
||||
documentName: doc.documentName || existingDoc.documentName,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
await tx.hostDocuments.create({
|
||||
data: {
|
||||
hostXid: updatedHost.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
@@ -740,62 +722,53 @@ export class HostService {
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await tx.hostParent.update({
|
||||
where: { id: parentRecord.id },
|
||||
data: {
|
||||
companyName: parentCompanyData.companyName,
|
||||
address1: parentCompanyData.address1 || null,
|
||||
address2: parentCompanyData.address2 || null,
|
||||
cities: parentCompanyData.cityXid
|
||||
? { connect: { id: parentCompanyData.cityXid } }
|
||||
: undefined,
|
||||
states: parentCompanyData.stateXid
|
||||
? { connect: { id: parentCompanyData.stateXid } }
|
||||
: undefined,
|
||||
countries: parentCompanyData.countryXid
|
||||
? { connect: { id: parentCompanyData.countryXid } }
|
||||
: undefined,
|
||||
pinCode: parentCompanyData.pinCode || null,
|
||||
logoPath: parentCompanyData.logoPath || null,
|
||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||
panNumber: parentCompanyData.panNumber || null,
|
||||
gstNumber: parentCompanyData.gstNumber || null,
|
||||
formationDate: parentCompanyData.formationDate
|
||||
? new Date(parentCompanyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: parentCompanyData.companyTypeXid
|
||||
? { connect: { id: parentCompanyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: parentCompanyData.websiteUrl || null,
|
||||
instagramUrl: parentCompanyData.instagramUrl || null,
|
||||
facebookUrl: parentCompanyData.facebookUrl || null,
|
||||
linkedinUrl: parentCompanyData.linkedinUrl || null,
|
||||
twitterUrl: parentCompanyData.twitterUrl || null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (parentDocuments?.length) {
|
||||
for (const doc of parentDocuments) {
|
||||
const existingParentDoc = await tx.hostParenetDocuments.findFirst({
|
||||
where: {
|
||||
hostParentXid: parentRecord.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
},
|
||||
});
|
||||
// parent logic untouched
|
||||
if (companyData.isSubsidairy) {
|
||||
const parentRecords = existingHostCompany.hostParent;
|
||||
const parentRecord = Array.isArray(parentRecords) ? parentRecords[0] : parentRecords;
|
||||
|
||||
if (existingParentDoc) {
|
||||
await tx.hostParenetDocuments.update({
|
||||
where: { id: existingParentDoc.id },
|
||||
data: {
|
||||
filePath: doc.filePath,
|
||||
documentName: doc.documentName || existingParentDoc.documentName,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
if (!parentRecord) {
|
||||
const createdParent = await tx.hostParent.create({
|
||||
data: {
|
||||
host: { connect: { id: updatedHost.id } },
|
||||
companyName: parentCompanyData.companyName,
|
||||
address1: parentCompanyData.address1 || null,
|
||||
address2: parentCompanyData.address2 || null,
|
||||
cities: parentCompanyData.cityXid
|
||||
? { connect: { id: parentCompanyData.cityXid } }
|
||||
: undefined,
|
||||
states: parentCompanyData.stateXid
|
||||
? { connect: { id: parentCompanyData.stateXid } }
|
||||
: undefined,
|
||||
countries: parentCompanyData.countryXid
|
||||
? { connect: { id: parentCompanyData.countryXid } }
|
||||
: undefined,
|
||||
pinCode: parentCompanyData.pinCode || null,
|
||||
logoPath: parentCompanyData.logoPath || null,
|
||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||
panNumber: parentCompanyData.panNumber || null,
|
||||
gstNumber: parentCompanyData.gstNumber || null,
|
||||
formationDate: parentCompanyData.formationDate
|
||||
? new Date(parentCompanyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: parentCompanyData.companyTypeXid
|
||||
? { connect: { id: parentCompanyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: parentCompanyData.websiteUrl || null,
|
||||
instagramUrl: parentCompanyData.instagramUrl || null,
|
||||
facebookUrl: parentCompanyData.facebookUrl || null,
|
||||
linkedinUrl: parentCompanyData.linkedinUrl || null,
|
||||
twitterUrl: parentCompanyData.twitterUrl || null,
|
||||
},
|
||||
});
|
||||
|
||||
if (parentDocuments?.length) {
|
||||
for (const doc of parentDocuments) {
|
||||
await tx.hostParenetDocuments.create({
|
||||
data: {
|
||||
hostParentXid: parentRecord.id,
|
||||
hostParentXid: createdParent.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
@@ -803,53 +776,116 @@ export class HostService {
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await tx.hostParent.update({
|
||||
where: { id: parentRecord.id },
|
||||
data: {
|
||||
companyName: parentCompanyData.companyName,
|
||||
address1: parentCompanyData.address1 || null,
|
||||
address2: parentCompanyData.address2 || null,
|
||||
cities: parentCompanyData.cityXid
|
||||
? { connect: { id: parentCompanyData.cityXid } }
|
||||
: undefined,
|
||||
states: parentCompanyData.stateXid
|
||||
? { connect: { id: parentCompanyData.stateXid } }
|
||||
: undefined,
|
||||
countries: parentCompanyData.countryXid
|
||||
? { connect: { id: parentCompanyData.countryXid } }
|
||||
: undefined,
|
||||
pinCode: parentCompanyData.pinCode || null,
|
||||
logoPath: parentCompanyData.logoPath || null,
|
||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||
panNumber: parentCompanyData.panNumber || null,
|
||||
gstNumber: parentCompanyData.gstNumber || null,
|
||||
formationDate: parentCompanyData.formationDate
|
||||
? new Date(parentCompanyData.formationDate as any)
|
||||
: null,
|
||||
companyTypes: parentCompanyData.companyTypeXid
|
||||
? { connect: { id: parentCompanyData.companyTypeXid } }
|
||||
: undefined,
|
||||
websiteUrl: parentCompanyData.websiteUrl || null,
|
||||
instagramUrl: parentCompanyData.instagramUrl || null,
|
||||
facebookUrl: parentCompanyData.facebookUrl || null,
|
||||
linkedinUrl: parentCompanyData.linkedinUrl || null,
|
||||
twitterUrl: parentCompanyData.twitterUrl || null,
|
||||
},
|
||||
});
|
||||
|
||||
if (parentDocuments?.length) {
|
||||
for (const doc of parentDocuments) {
|
||||
const existingParentDoc = await tx.hostParenetDocuments.findFirst({
|
||||
where: {
|
||||
hostParentXid: parentRecord.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
},
|
||||
});
|
||||
|
||||
if (existingParentDoc) {
|
||||
await tx.hostParenetDocuments.update({
|
||||
where: { id: existingParentDoc.id },
|
||||
data: {
|
||||
filePath: doc.filePath,
|
||||
documentName: doc.documentName || existingParentDoc.documentName,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
await tx.hostParenetDocuments.create({
|
||||
data: {
|
||||
hostParentXid: parentRecord.id,
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
filePath: doc.filePath,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const previousParent = existingHostCompany.hostParent;
|
||||
let prevParentId = null;
|
||||
|
||||
if (Array.isArray(previousParent) && previousParent.length) {
|
||||
prevParentId = previousParent[0].id;
|
||||
} else if (previousParent && typeof previousParent === 'object' && 'id' in previousParent) {
|
||||
prevParentId = previousParent.id;
|
||||
}
|
||||
|
||||
if (prevParentId) {
|
||||
await tx.hostParenetDocuments.deleteMany({
|
||||
where: { hostParentXid: prevParentId },
|
||||
});
|
||||
await tx.hostParent.delete({ where: { id: prevParentId } });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const previousParent = existingHostCompany.hostParent;
|
||||
let prevParentId = null;
|
||||
|
||||
if (Array.isArray(previousParent) && previousParent.length) {
|
||||
prevParentId = previousParent[0].id;
|
||||
} else if (previousParent && typeof previousParent === 'object' && 'id' in previousParent) {
|
||||
prevParentId = previousParent.id;
|
||||
}
|
||||
|
||||
if (prevParentId) {
|
||||
await tx.hostParenetDocuments.deleteMany({
|
||||
where: { hostParentXid: prevParentId },
|
||||
});
|
||||
await tx.hostParent.delete({ where: { id: prevParentId } });
|
||||
}
|
||||
}
|
||||
|
||||
// ⭐ FIX — USE updatedHost instead of re-querying hostHeader
|
||||
await tx.hostTrack.create({
|
||||
data: {
|
||||
hostXid: updatedHost.id,
|
||||
updatedByRole: ROLE_NAME.HOST,
|
||||
updatedByXid: user_xid,
|
||||
trackStatus: updatedHost.hostStatusInternal,
|
||||
},
|
||||
});
|
||||
|
||||
// suggestion update unchanged
|
||||
if (!isDraft) {
|
||||
await tx.hostSuggestion.updateMany({
|
||||
where: { hostXid: updatedHost.id, isActive: true, isreviewed: false },
|
||||
// ⭐ FIX — USE updatedHost instead of re-querying hostHeader
|
||||
await tx.hostTrack.create({
|
||||
data: {
|
||||
isreviewed: true,
|
||||
reviewedByXid: user_xid,
|
||||
reviewOn: new Date(),
|
||||
hostXid: updatedHost.id,
|
||||
updatedByRole: ROLE_NAME.HOST,
|
||||
updatedByXid: user_xid,
|
||||
trackStatus: updatedHost.hostStatusInternal,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return updatedHost;
|
||||
});
|
||||
}
|
||||
// suggestion update unchanged
|
||||
if (!isDraft) {
|
||||
await tx.hostSuggestion.updateMany({
|
||||
where: { hostXid: updatedHost.id, isActive: true, isreviewed: false },
|
||||
data: {
|
||||
isreviewed: true,
|
||||
reviewedByXid: user_xid,
|
||||
reviewOn: new Date(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return updatedHost;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async getSuggestionDetails(user_xid: number) {
|
||||
const hostDetails = await this.prisma.hostHeader.findFirst({
|
||||
@@ -954,7 +990,7 @@ export class HostService {
|
||||
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 },
|
||||
where: { activityXid, isActive: true },
|
||||
include: {
|
||||
pqqQuestions: {
|
||||
include: {
|
||||
@@ -1020,7 +1056,7 @@ export class HostService {
|
||||
|
||||
// Overall percent
|
||||
const overallPercentage =
|
||||
totalMaxPoints > 0 ? (totalUserPoints / totalMaxPoints) * 100 : 0;
|
||||
totalMaxPoints > 0 ? round2((totalUserPoints / totalMaxPoints) * 100) : 0;
|
||||
|
||||
// ---------- 🔥 ONLY FIRST 2 CATEGORIES ----------
|
||||
const categoryArray = Object.values(categories);
|
||||
@@ -1035,7 +1071,7 @@ export class HostService {
|
||||
|
||||
for (const c of topTwo) {
|
||||
categoryWise[c.categoryName] =
|
||||
c.maxPoints > 0 ? (c.userPoints / c.maxPoints) * 100 : 0;
|
||||
c.maxPoints > 0 ? round2((c.userPoints / c.maxPoints) * 100) : 0;
|
||||
}
|
||||
|
||||
await this.prisma.activities.update({
|
||||
@@ -1043,13 +1079,9 @@ export class HostService {
|
||||
id: activityXid
|
||||
},
|
||||
data: {
|
||||
totalScore: overallPercentage,
|
||||
sustainabilityScore: categoryWise.Sustainability,
|
||||
safetyScore: categoryWise.Safety,
|
||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.PQQ_SUBMITTED,
|
||||
activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.PQ_IN_REVIEW,
|
||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.PQQ_TO_REVIEW,
|
||||
amDisplayStatus: ACTIVITY_AM_DISPLAY_STATUS.NEW
|
||||
totalScore: round2(overallPercentage),
|
||||
sustainabilityScore: round2(categoryWise.Sustainability),
|
||||
safetyScore: round2(categoryWise.Safety),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1080,24 +1112,23 @@ export class HostService {
|
||||
async findHeaderByCompositeKey(
|
||||
activityXid: number,
|
||||
pqqQuestionXid: number,
|
||||
pqqAnswerXid: number,
|
||||
) {
|
||||
return await this.prisma.activityPQQheader.findFirst({
|
||||
where: {
|
||||
activityXid,
|
||||
pqqQuestionXid,
|
||||
pqqAnswerXid,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateHeader(headerId: number, comments?: string | null) {
|
||||
async updateHeader(headerId: number, pqqAnswerXid: number, comments?: string | null) {
|
||||
return await this.prisma.activityPQQheader.update({
|
||||
where: {
|
||||
id: headerId,
|
||||
},
|
||||
data: {
|
||||
comments: comments || null, // Handle null comments
|
||||
pqqAnswerXid: pqqAnswerXid,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
@@ -1124,6 +1155,32 @@ export class HostService {
|
||||
});
|
||||
}
|
||||
|
||||
async submitpqqforreview(activity_xid: number) {
|
||||
const activity = await this.prisma.activities.findFirst({
|
||||
where: { id: activity_xid, isActive: true },
|
||||
select: {
|
||||
id: true,
|
||||
activityTitle: true,
|
||||
activityRefNumber: true,
|
||||
}
|
||||
})
|
||||
|
||||
if (!activity) {
|
||||
throw new ApiError(404, "Activity not found")
|
||||
}
|
||||
|
||||
await this.prisma.activities.update({
|
||||
where: { id: activity_xid },
|
||||
data: {
|
||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.PQ_SUBMITTED,
|
||||
activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.PQ_IN_REVIEW,
|
||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.PQ_TO_REVIEW,
|
||||
amDisplayStatus: ACTIVITY_AM_DISPLAY_STATUS.NEW
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
async updateSupportingFile(
|
||||
supportingFileId: number,
|
||||
mimeType: string,
|
||||
|
||||
Reference in New Issue
Block a user