made getall document country city and replacing the files on s3 when updating the company details sending mail to am or admin
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
hostDocumentsSchema
|
||||
} from '../../../common/utils/validation/host/hostCompanyDetails.validation';
|
||||
import { HostService } from '../../host/services/host.service';
|
||||
import { sendEmailToAM, sendEmailToMinglarAdmin } from '../services/sendHostResubmitEmailToAM.service';
|
||||
|
||||
const prisma = new PrismaService();
|
||||
const hostService = new HostService(prisma);
|
||||
@@ -50,16 +51,28 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
|
||||
// 2) multipart check
|
||||
const contentType = event.headers['content-type'] || event.headers['Content-Type'];
|
||||
if (!contentType?.startsWith('multipart/form-data')) throw new ApiError(400, 'Content-Type must be multipart/form-data.');
|
||||
if (!event.isBase64Encoded) throw new ApiError(400, 'Event body must be base64 encoded for multipart uploads.');
|
||||
if (!contentType?.includes('multipart/form-data')) {
|
||||
throw new ApiError(400, 'Content-Type must be multipart/form-data.');
|
||||
}
|
||||
|
||||
// Handle both base64 and non-base64 encoded bodies
|
||||
let bodyBuffer: Buffer;
|
||||
if (event.isBase64Encoded) {
|
||||
bodyBuffer = Buffer.from(event.body as string, 'base64');
|
||||
} else {
|
||||
bodyBuffer = Buffer.from(event.body as string, 'binary');
|
||||
}
|
||||
|
||||
const bodyBuffer = Buffer.from(event.body as string, 'base64');
|
||||
const fields: Record<string, any> = {};
|
||||
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
||||
|
||||
// 3) parse with Busboy
|
||||
// 3) parse with Busboy - FIXED VERSION
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const bb = Busboy({ headers: { 'content-type': contentType } });
|
||||
const bb = Busboy({
|
||||
headers: {
|
||||
'content-type': contentType
|
||||
}
|
||||
});
|
||||
|
||||
bb.on('file', (fieldname, file, info) => {
|
||||
const { filename, mimeType } = info;
|
||||
@@ -70,36 +83,64 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
file.on('data', (chunk) => {
|
||||
totalSize += chunk.length;
|
||||
if (totalSize > MAX_SIZE) {
|
||||
file.resume();
|
||||
return reject(new ApiError(400, `File ${filename} exceeds 5MB limit.`));
|
||||
file.destroy(new Error(`File ${filename} exceeds 5MB limit.`));
|
||||
return;
|
||||
}
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
file.on('end', () => {
|
||||
files.push({
|
||||
buffer: Buffer.concat(chunks),
|
||||
mimeType,
|
||||
fileName: filename,
|
||||
fieldName: fieldname,
|
||||
});
|
||||
if (chunks.length > 0) {
|
||||
files.push({
|
||||
buffer: Buffer.concat(chunks),
|
||||
mimeType: mimeType || 'application/octet-stream',
|
||||
fileName: filename || 'unknown',
|
||||
fieldName: fieldname,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
file.on('error', (error) => {
|
||||
reject(new ApiError(400, `File upload error: ${error.message}`));
|
||||
});
|
||||
});
|
||||
|
||||
bb.on('field', (fieldname, val) => {
|
||||
// Keep raw string for JSON parse later; try parse for convenience
|
||||
try {
|
||||
fields[fieldname] = JSON.parse(val);
|
||||
} catch {
|
||||
fields[fieldname] = val;
|
||||
}
|
||||
// Store as string initially, parse later in normalizeJsonField
|
||||
fields[fieldname] = val;
|
||||
});
|
||||
|
||||
bb.on('close', resolve);
|
||||
bb.on('error', reject);
|
||||
bb.end(bodyBuffer);
|
||||
bb.on('close', () => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
bb.on('error', (error) => {
|
||||
reject(new ApiError(400, `Multipart parsing error: ${error.message}`));
|
||||
});
|
||||
|
||||
bb.write(bodyBuffer);
|
||||
bb.end();
|
||||
});
|
||||
|
||||
if (fields.userProfile) {
|
||||
const userProfileRaw = normalizeJsonField(fields, "userProfile");
|
||||
if (userProfileRaw) {
|
||||
const { firstName, lastName, mobileNumber } = userProfileRaw;
|
||||
|
||||
// Update user profile if provided
|
||||
if (firstName || lastName || mobileNumber) {
|
||||
await prisma.user.update({
|
||||
where: { id: userInfo.id },
|
||||
data: {
|
||||
...(firstName && { firstName }),
|
||||
...(lastName && { lastName }),
|
||||
...(mobileNumber && { mobileNumber }),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4) Validate required root fields
|
||||
if (!fields.companyDetails) throw new ApiError(400, 'Missing companyDetails field.');
|
||||
if (!fields.documents) throw new ApiError(400, 'Missing documents field.');
|
||||
@@ -108,6 +149,83 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
const companyDetailsRaw = normalizeJsonField(fields, "companyDetails");
|
||||
if (!companyDetailsRaw) throw new ApiError(400, "companyDetails is required.");
|
||||
|
||||
// Get existing host to determine host ID for folder structure
|
||||
const existingHost = await prisma.hostHeader.findFirst({
|
||||
where: { userXid: userInfo.id },
|
||||
});
|
||||
|
||||
let hostId: number;
|
||||
if (existingHost) {
|
||||
hostId = existingHost.id;
|
||||
} else {
|
||||
// For new hosts, we'll use user ID temporarily and update after host creation
|
||||
hostId = userInfo.id;
|
||||
}
|
||||
|
||||
// Define uploadToS3 function with proper folder structure using fieldName for filenames
|
||||
// Define uploadToS3 function with proper folder structure using fieldName for filenames
|
||||
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, folderType: 'logo' | 'documents' | 'parent_company', documentTypeXid?: number, fieldName?: string) {
|
||||
let s3Key: string;
|
||||
|
||||
// Sanitize file name: remove special characters and spaces
|
||||
const sanitizeFileName = (name: string) => {
|
||||
return name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9.]/g, '_') // Replace special characters with underscore
|
||||
.replace(/_+/g, '_') // Replace multiple underscores with single
|
||||
.replace(/^_+|_+$/g, ''); // Remove leading/trailing underscores
|
||||
};
|
||||
|
||||
// Get file extension from original file name
|
||||
const fileExtension = originalName.split('.').pop() || 'pdf';
|
||||
|
||||
// Determine folder structure based on type
|
||||
if (folderType === 'logo') {
|
||||
// Logo: Documents/Host/logo/{HostID}/{sanitized_filename}
|
||||
const sanitizedFileName = sanitizeFileName(originalName);
|
||||
s3Key = `Documents/Host/logo/${hostId}/${sanitizedFileName}`;
|
||||
} else if (folderType === 'documents' && documentTypeXid && fieldName) {
|
||||
// Host Documents: Documents/Host/documents/{HostID}/{documentTypeXid}_{fieldName}.{extension}
|
||||
const fileName = `${documentTypeXid}_${fieldName}.${fileExtension}`;
|
||||
const sanitizedFileName = sanitizeFileName(fileName);
|
||||
s3Key = `Documents/Host/documents/${hostId}/${sanitizedFileName}`;
|
||||
} else if (folderType === 'parent_company' && documentTypeXid && fieldName) {
|
||||
// Parent Documents: Documents/Host/parent_company/{HostID}/{documentTypeXid}_{fieldName}.{extension}
|
||||
const fileName = `${documentTypeXid}_${fieldName}.${fileExtension}`;
|
||||
const sanitizedFileName = sanitizeFileName(fileName);
|
||||
s3Key = `Documents/Host/parent_company/${hostId}/${sanitizedFileName}`;
|
||||
} else {
|
||||
throw new ApiError(400, 'Invalid folder type or missing documentTypeXid/fieldName');
|
||||
}
|
||||
|
||||
// Upload new file (S3 will automatically replace if same key exists)
|
||||
await s3
|
||||
.upload({
|
||||
Bucket: config.aws.bucketName,
|
||||
Key: s3Key,
|
||||
Body: buffer,
|
||||
ContentType: mimeType,
|
||||
ACL: 'private',
|
||||
})
|
||||
.promise();
|
||||
|
||||
console.log(`File uploaded successfully: ${s3Key}`);
|
||||
return `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/${s3Key}`;
|
||||
}
|
||||
|
||||
// 5.5) Handle company logo upload
|
||||
const logoFile = files.find((f) => f.fieldName === 'companyLogo');
|
||||
if (logoFile) {
|
||||
const logoPath = await uploadToS3(
|
||||
logoFile.buffer,
|
||||
logoFile.mimeType,
|
||||
logoFile.fileName,
|
||||
'logo'
|
||||
);
|
||||
companyDetailsRaw.logoPath = logoPath;
|
||||
console.log('Company logo uploaded:', logoPath);
|
||||
}
|
||||
|
||||
// 6) Zod validation for companyDetails (includes optional parentCompany)
|
||||
const companyValidation = hostCompanyDetailsSchema.safeParse(companyDetailsRaw);
|
||||
if (!companyValidation.success) {
|
||||
@@ -129,21 +247,21 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
}
|
||||
const documentsMetadata = documentsMetadataRaw.map((d: any) => ({
|
||||
...d,
|
||||
owner: d.owner === 'parent' ? 'parent' : 'host', // default host
|
||||
owner: d.owner || 'host', // default to host
|
||||
}));
|
||||
|
||||
// 9) Map uploaded files to metadata (one entry per file - Q2 = A)
|
||||
// 8) Map uploaded files to metadata
|
||||
const documentMetadata = documentsMetadata.map((doc: any) => {
|
||||
const file = files.find((f) => f.fieldName === doc.fieldName);
|
||||
if (!file) throw new ApiError(400, `File not found for field: ${doc.fieldName}`);
|
||||
return { ...doc, file };
|
||||
});
|
||||
|
||||
// 10) Split host vs parent docs
|
||||
// 9) Split host vs parent docs
|
||||
const hostDocs = documentMetadata.filter((d) => d.owner === 'host');
|
||||
const parentDocs = documentMetadata.filter((d) => d.owner === 'parent');
|
||||
|
||||
// 11) Ensure required docs for host exist (IDs 1,2,3,4)
|
||||
// 10) Ensure required docs for host exist (IDs 1,2,3,4)
|
||||
const hostUploadedTypes = hostDocs.map((d) => d.documentTypeXid);
|
||||
const requiredHostTypes = Object.values(REQUIRED_DOC_TYPES);
|
||||
const missingHostDocs = requiredHostTypes.filter((typeId) => !hostUploadedTypes.includes(typeId));
|
||||
@@ -151,7 +269,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
throw new ApiError(400, `Missing mandatory documents for host: ${missingHostDocs.join(', ')}`);
|
||||
}
|
||||
|
||||
// 12) If isSubsidairy === true and parentCompany provided -> validate parent company & docs
|
||||
// 11) If isSubsidairy === true and parentCompany provided -> validate parent company & docs
|
||||
let parsedParentCompany: any = null;
|
||||
if (parsedCompany.isSubsidairy) {
|
||||
if (!parsedCompany.parentCompany) {
|
||||
@@ -163,16 +281,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
const message = parentValidation.error.issues.map((i) => i.message).join(', ');
|
||||
throw new ApiError(400, `Parent company validation failed: ${message}`);
|
||||
}
|
||||
|
||||
let parentCompanyRaw = parsedCompany.parentCompany;
|
||||
if (typeof parentCompanyRaw === "string") {
|
||||
try {
|
||||
parentCompanyRaw = JSON.parse(parentCompanyRaw);
|
||||
} catch {
|
||||
throw new ApiError(400, "Invalid JSON in parentCompany.");
|
||||
}
|
||||
}
|
||||
parsedParentCompany = parentCompanyRaw;
|
||||
parsedParentCompany = parsedCompany.parentCompany;
|
||||
|
||||
const parentUploadedTypes = parentDocs.map((d) => d.documentTypeXid);
|
||||
const requiredParentTypes = Object.values(REQUIRED_DOC_TYPES);
|
||||
@@ -182,49 +291,47 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
}
|
||||
}
|
||||
|
||||
// 13) Upload files to S3 (host docs under Documents/Host/, parent docs under Documents/Host/parent_company/)
|
||||
// 12) Upload files to S3 with proper folder structure using fieldName for filenames
|
||||
const uploadedHostDocs: Array<{ documentTypeXid: number; documentName: string; filePath: string }> = [];
|
||||
const uploadedParentDocs: Array<{ documentTypeXid: number; documentName: string; filePath: string }> = [];
|
||||
|
||||
async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string, prefix: string) {
|
||||
const uniqueKey = `${userInfo.id}_${crypto.randomUUID()}_${originalName}`;
|
||||
const s3Key = `${prefix}/${uniqueKey}`;
|
||||
await s3
|
||||
.upload({
|
||||
Bucket: config.aws.bucketName,
|
||||
Key: s3Key,
|
||||
Body: buffer,
|
||||
ContentType: mimeType,
|
||||
ACL: 'private',
|
||||
})
|
||||
.promise();
|
||||
|
||||
return `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/${s3Key}`;
|
||||
}
|
||||
|
||||
// upload host files
|
||||
// Upload host documents with proper folder structure using fieldName
|
||||
for (const doc of hostDocs) {
|
||||
const filePath = await uploadToS3(doc.file.buffer, doc.file.mimeType, doc.file.fileName, 'Documents/Host');
|
||||
const filePath = await uploadToS3(
|
||||
doc.file.buffer,
|
||||
doc.file.mimeType,
|
||||
doc.file.fileName, // Use original file name for extension
|
||||
'documents',
|
||||
doc.documentTypeXid,
|
||||
doc.fieldName // Use fieldName for the filename
|
||||
);
|
||||
uploadedHostDocs.push({
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
documentName: doc.documentName, // Keep documentName for database
|
||||
filePath,
|
||||
});
|
||||
}
|
||||
|
||||
// upload parent files (if any)
|
||||
// Upload parent company documents with proper folder structure using fieldName
|
||||
if (parentDocs.length > 0) {
|
||||
for (const doc of parentDocs) {
|
||||
const filePath = await uploadToS3(doc.file.buffer, doc.file.mimeType, doc.file.fileName, 'Documents/Host/parent_company');
|
||||
const filePath = await uploadToS3(
|
||||
doc.file.buffer,
|
||||
doc.file.mimeType,
|
||||
doc.file.fileName, // Use original file name for extension
|
||||
'parent_company',
|
||||
doc.documentTypeXid,
|
||||
doc.fieldName // Use fieldName for the filename
|
||||
);
|
||||
uploadedParentDocs.push({
|
||||
documentTypeXid: doc.documentTypeXid,
|
||||
documentName: doc.documentName,
|
||||
documentName: doc.documentName, // Keep documentName for database
|
||||
filePath,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 14) Persist using hostService
|
||||
// 13) Persist using hostService
|
||||
const createdOrUpdated = await hostService.addOrUpdateCompanyDetails(
|
||||
userInfo.id,
|
||||
parsedCompany,
|
||||
@@ -235,7 +342,31 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
|
||||
if (!createdOrUpdated) throw new ApiError(400, 'Failed to add/update company details.');
|
||||
|
||||
// 15) Success
|
||||
// Update hostId if it was a new creation
|
||||
if (!existingHost) {
|
||||
hostId = createdOrUpdated.id;
|
||||
console.log(`Host created with ID: ${hostId}`);
|
||||
}
|
||||
|
||||
const getSuggestionDetails = await hostService.getSuggestionDetails(userInfo.id)
|
||||
|
||||
if (getSuggestionDetails && getSuggestionDetails.hostDetails.accountManagerXid !== null) {
|
||||
await sendEmailToAM(
|
||||
getSuggestionDetails.hostDetails.accountManager.emailAddress,
|
||||
getSuggestionDetails.hostDetails.accountManager.firstName,
|
||||
getSuggestionDetails.hostDetails.companyName,
|
||||
getSuggestionDetails.hostDetails.hostRefNumber
|
||||
);
|
||||
} else {
|
||||
await sendEmailToMinglarAdmin(
|
||||
config.MinglarAdminEmail,
|
||||
config.MinglarAdminName,
|
||||
getSuggestionDetails.hostDetails.companyName,
|
||||
getSuggestionDetails.hostDetails.hostRefNumber
|
||||
)
|
||||
}
|
||||
|
||||
// 14) Success
|
||||
return {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
@@ -252,4 +383,4 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
console.error('❌ Error in addCompanyDetails:', error);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -480,6 +480,50 @@ export class HostService {
|
||||
});
|
||||
}
|
||||
|
||||
async getSuggestionDetails(user_xid: number) {
|
||||
const hostDetails = await this.prisma.hostHeader.findFirst({
|
||||
where: { userXid: user_xid, isActive: true },
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
emailAddress: true,
|
||||
firstName: true,
|
||||
}
|
||||
},
|
||||
accountManager: {
|
||||
select: {
|
||||
id: true,
|
||||
emailAddress: true,
|
||||
firstName: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!hostDetails) {
|
||||
return { hostSuggestionDetails: [], hostDetails: null };
|
||||
}
|
||||
|
||||
const hostSuggestionDetails = await this.prisma.hostSuggestion.findMany({
|
||||
where: { hostXid: hostDetails.id, isActive: true, isreviewed: false }
|
||||
});
|
||||
|
||||
if (hostSuggestionDetails) {
|
||||
await this.prisma.hostSuggestion.updateMany({
|
||||
where: { hostXid: hostDetails.id, isActive: true, isreviewed: false },
|
||||
data: {
|
||||
isreviewed: true,
|
||||
reviewedByXid: hostDetails.id,
|
||||
reviewOn: new Date(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return { hostSuggestionDetails, hostDetails };
|
||||
}
|
||||
|
||||
|
||||
|
||||
async generateHostRefNumber(tx: any) {
|
||||
const lastHost = await tx.hostHeader.findFirst({
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { brevoService } from "@/common/email/brevoApi";
|
||||
import ApiError from "@/common/utils/helper/ApiError";
|
||||
|
||||
export async function sendEmailToAM(
|
||||
emailAddress: string,
|
||||
amName: string,
|
||||
hostCompanyName: string,
|
||||
hostRefNumber: string
|
||||
): Promise<{
|
||||
sent: boolean;
|
||||
// messageId: string
|
||||
}> {
|
||||
|
||||
const subject = "Host Application Re-Submited";
|
||||
|
||||
const htmlContent = `
|
||||
<p>Dear ${amName},</p>
|
||||
<p>Host ${hostCompanyName} with reference number: <strong>${hostRefNumber}</strong> has re-submited the application with implimented suggestions.</p>
|
||||
<p>Please review their appliaction and take the necessary action.</p>
|
||||
<p>Best regards,<br/>Minglar Team</p>
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await brevoService.sendEmail({
|
||||
recipients: [{ email: emailAddress }],
|
||||
subject,
|
||||
htmlContent,
|
||||
});
|
||||
|
||||
// console.log("📧 Email sent successfully:", result);
|
||||
|
||||
return {
|
||||
sent: true,
|
||||
// messageId: result.messageId
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Brevo email send failed:", err);
|
||||
throw new ApiError(500, "Failed to send OTP to host via email.");
|
||||
}
|
||||
}
|
||||
|
||||
export async function sendEmailToMinglarAdmin(
|
||||
emailAddress: string,
|
||||
minglarAdminName: string,
|
||||
hostCompanyName: string,
|
||||
hostRefNumber: string
|
||||
): Promise<{
|
||||
sent: boolean;
|
||||
// messageId: string
|
||||
}> {
|
||||
|
||||
const subject = "New Host Application Recieved";
|
||||
|
||||
const htmlContent = `
|
||||
<p>Dear ${minglarAdminName},</p>
|
||||
<p>Host ${hostCompanyName} with reference number: <strong>${hostRefNumber}</strong> has submited their application.</p>
|
||||
<p>Please review their appliaction and take the necessary action.</p>
|
||||
<p>Best regards,<br/>Minglar Team</p>
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await brevoService.sendEmail({
|
||||
recipients: [{ email: emailAddress }],
|
||||
subject,
|
||||
htmlContent,
|
||||
});
|
||||
|
||||
// console.log("📧 Email sent successfully:", result);
|
||||
|
||||
return {
|
||||
sent: true,
|
||||
// messageId: result.messageId
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Brevo email send failed:", err);
|
||||
throw new ApiError(500, "Failed to send OTP to host via email.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
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 { PrePopulateService } from '../services/prepopulate.service';
|
||||
import { verifyHostToken } from '@/common/middlewares/jwt/authForHost';
|
||||
|
||||
const prismaService = new PrismaService();
|
||||
const prePopulateService = new PrePopulateService(prismaService);
|
||||
|
||||
export const handler = safeHandler(async (
|
||||
event: APIGatewayProxyEvent,
|
||||
context?: Context
|
||||
): Promise<APIGatewayProxyResult> => {
|
||||
// Extract token from headers
|
||||
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token']
|
||||
if (!token) {
|
||||
throw new ApiError(400, 'This is a protected route. Please provide a valid token.');
|
||||
}
|
||||
|
||||
// Authenticate user using the shared authForHost function
|
||||
await verifyHostToken(token);
|
||||
|
||||
const result = await prePopulateService.getAllDocumentTypeWithCountryStateCity();
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
success: true,
|
||||
message: 'Data retrieved successfully',
|
||||
data: result,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -59,6 +59,26 @@ export class PrePopulateService {
|
||||
});
|
||||
}
|
||||
|
||||
async getAllDocumentTypeWithCountryStateCity() {
|
||||
const [documentDetails, countryDetails, stateDetails, cityDetails] =
|
||||
await this.prisma.$transaction([
|
||||
this.prisma.documentType.findMany({
|
||||
where: { isActive: true, isVisible: true },
|
||||
orderBy: { displayOrder: 'asc' }
|
||||
}),
|
||||
this.prisma.countries.findMany({
|
||||
where: { isActive: true },
|
||||
}),
|
||||
this.prisma.states.findMany({
|
||||
where: { isActive: true }
|
||||
}),
|
||||
this.prisma.cities.findMany({
|
||||
where: { isActive: true }
|
||||
})
|
||||
]);
|
||||
|
||||
return { documentDetails, countryDetails, stateDetails, cityDetails };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user