From e5861654e9a2b7ad5d22e3913f8fccb0bce7ef53 Mon Sep 17 00:00:00 2001 From: Mayank Mishra Date: Mon, 1 Dec 2025 13:26:06 +0530 Subject: [PATCH] Enhance company types management: updated schema to include display order and relationships, modified validation to use company type XID, and seeded initial company types data. Updated services to reflect new structure and ensure proper data handling. --- prisma/schema.prisma | 41 +++++++----- prisma/seed.ts | 43 +++++++++++- .../host/hostCompanyDetails.validation.ts | 33 +++++----- src/modules/host/services/host.service.ts | 66 ++++++++++++++----- .../minglaradmin/services/minglar.service.ts | 18 +++++ .../services/prepopulate.service.ts | 13 ++-- 6 files changed, 159 insertions(+), 55 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 4d713bf..4bb645c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -405,12 +405,15 @@ model FoodCuisines { } model CompanyTypes { - id Int @id @default(autoincrement()) - companyTypeName String @unique @map("company_type_name") @db.VarChar(30) - isActive Boolean @default(true) @map("is_active") - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - deletedAt DateTime? @map("deleted_at") + id Int @id @default(autoincrement()) + companyTypeName String @unique @map("company_type_name") @db.VarChar(100) + displayOrder Int @map("display_order") + isActive Boolean @default(true) @map("is_active") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + deletedAt DateTime? @map("deleted_at") + hostHeaders HostHeader[] + hostParents HostParent[] @@map("company_types") @@schema("mst") @@ -664,12 +667,13 @@ model HostHeader { panNumber String? @map("pan_number") @db.VarChar(30) gstNumber String? @map("gst_number") @db.VarChar(30) formationDate DateTime? @map("formation_date") - companyType String? @map("company_type") @db.VarChar(30) - websiteUrl String? @map("website_url") @db.VarChar(50) - instagramUrl String? @map("instagram_url") @db.VarChar(80) - facebookUrl String? @map("facebook_url") @db.VarChar(80) - linkedinUrl String? @map("linkedin_url") @db.VarChar(80) - twitterUrl String? @map("twitter_url") @db.VarChar(80) + companyTypeXid Int? @map("company_type_xid") + companyTypes CompanyTypes? @relation(fields: [companyTypeXid], references: [id], onDelete: Restrict) + websiteUrl String? @map("website_url") @db.VarChar(250) + instagramUrl String? @map("instagram_url") @db.VarChar(250) + facebookUrl String? @map("facebook_url") @db.VarChar(250) + linkedinUrl String? @map("linkedin_url") @db.VarChar(250) + twitterUrl String? @map("twitter_url") @db.VarChar(250) currencyXid Int? @map("currency_xid") currencies Currencies? @relation(fields: [currencyXid], references: [id], onDelete: Restrict) stepper Int? @default(1) @map("stepper") @@ -785,12 +789,13 @@ model HostParent { panNumber String? @map("pan_number") @db.VarChar(30) gstNumber String? @map("gst_number") @db.VarChar(30) formationDate DateTime? @map("formation_date") - companyType String? @map("company_type") @db.VarChar(30) - websiteUrl String? @map("website_url") @db.VarChar(80) - instagramUrl String? @map("instagram_url") @db.VarChar(80) - facebookUrl String? @map("facebook_url") @db.VarChar(80) - linkedinUrl String? @map("linkedin_url") @db.VarChar(80) - twitterUrl String? @map("twitter_url") @db.VarChar(80) + companyTypeXid Int? @map("company_type_xid") + companyTypes CompanyTypes? @relation(fields: [companyTypeXid], references: [id], onDelete: Restrict) + websiteUrl String? @map("website_url") @db.VarChar(250) + instagramUrl String? @map("instagram_url") @db.VarChar(250) + facebookUrl String? @map("facebook_url") @db.VarChar(250) + linkedinUrl String? @map("linkedin_url") @db.VarChar(250) + twitterUrl String? @map("twitter_url") @db.VarChar(250) isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") diff --git a/prisma/seed.ts b/prisma/seed.ts index e60c1ea..e05e7a4 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,6 +1,10 @@ import { PrismaClient } from '@prisma/client'; +import { PrismaPg } from '@prisma/adapter-pg'; +import 'dotenv/config'; -const prisma = new PrismaClient(); +const prisma = new PrismaClient({ + adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }), +}); async function main() { // ✅ Countries @@ -133,6 +137,43 @@ async function main() { skipDuplicates: true, // prevents error if already seeded }); + // ✅ Company types data + await prisma.companyTypes.upsert({ + where: { companyTypeName: 'Proprietory' }, + update: {}, + create: { companyTypeName: 'Proprietory', displayOrder: 1 }, + }); + + await prisma.companyTypes.upsert({ + where: { companyTypeName: 'One Person Company' }, + update: {}, + create: { companyTypeName: 'One Person Company', displayOrder: 2 }, + }); + + await prisma.companyTypes.upsert({ + where: { companyTypeName: 'Limited Liability Partnership' }, + update: {}, + create: { companyTypeName: 'Limited Liability Partnership', displayOrder: 3 }, + }); + + await prisma.companyTypes.upsert({ + where: { companyTypeName: 'Partnership Firm' }, + update: {}, + create: { companyTypeName: 'Partnership Firm', displayOrder: 4 }, + }); + + await prisma.companyTypes.upsert({ + where: { companyTypeName: 'Private Limited, Public Limited' }, + update: {}, + create: { companyTypeName: 'Private Limited, Public Limited', displayOrder: 5 }, + }); + + await prisma.companyTypes.upsert({ + where: { companyTypeName: 'Non-Profit Organisation' }, + update: {}, + create: { companyTypeName: 'Non-Profit Organisation', displayOrder: 6 }, + }); + // ✅ Food Types await prisma.foodTypes.createMany({ data: [ diff --git a/src/common/utils/validation/host/hostCompanyDetails.validation.ts b/src/common/utils/validation/host/hostCompanyDetails.validation.ts index c480786..42038e8 100644 --- a/src/common/utils/validation/host/hostCompanyDetails.validation.ts +++ b/src/common/utils/validation/host/hostCompanyDetails.validation.ts @@ -45,15 +45,15 @@ export const parentCompanySchema = z.object({ message: "Formation date must be a valid date", }), - companyType: z.string() - .min(1, "Company type is required") - .max(30, "Company type cannot exceed 30 characters"), + companyTypeXid: z.number() + .min(1, "Company type XID is required"), + + websiteUrl: z.string().nullable().optional(), + instagramUrl: z.string().nullable().optional(), + facebookUrl: z.string().nullable().optional(), + linkedinUrl: z.string().nullable().optional(), + twitterUrl: z.string().nullable().optional(), - websiteUrl: z.string().url().max(80, "Website URL cannot exceed 80 characters").optional(), - instagramUrl: z.string().url().max(80, "Instagram URL cannot exceed 80 characters").optional(), - facebookUrl: z.string().url().max(80, "Facebook URL cannot exceed 80 characters").optional(), - linkedinUrl: z.string().url().max(80, "LinkedIn URL cannot exceed 80 characters").optional(), - twitterUrl: z.string().url().max(80, "Twitter URL cannot exceed 80 characters").optional(), }); @@ -106,15 +106,16 @@ export const hostCompanyDetailsSchema = z.object({ message: "Formation date must be a valid date", }), - companyType: z.string() - .min(1, "Company type is required") - .max(30, "Company type cannot exceed 30 characters"), + companyTypeXid: z.number() + .int("Company type must be a valid integer") + .min(1, "Company type is required"), + + websiteUrl: z.string().nullable().optional(), + instagramUrl: z.string().nullable().optional(), + facebookUrl: z.string().nullable().optional(), + linkedinUrl: z.string().nullable().optional(), + twitterUrl: z.string().nullable().optional(), - websiteUrl: z.string().url().max(50, "Website URL cannot exceed 50 characters").optional(), - instagramUrl: z.string().url().max(80, "Instagram URL cannot exceed 80 characters").optional(), - facebookUrl: z.string().url().max(80, "Facebook URL cannot exceed 80 characters").optional(), - linkedinUrl: z.string().url().max(80, "LinkedIn URL cannot exceed 80 characters").optional(), - twitterUrl: z.string().url().max(80, "Twitter URL cannot exceed 80 characters").optional(), parentCompany: parentCompanySchema.optional(), }); diff --git a/src/modules/host/services/host.service.ts b/src/modules/host/services/host.service.ts index 6d3d418..1a577e4 100644 --- a/src/modules/host/services/host.service.ts +++ b/src/modules/host/services/host.service.ts @@ -94,6 +94,12 @@ export class HostService { userRefNumber: true, } }, + companyTypes: { + select: { + id: true, + companyTypeName: true, + }, + }, HostSuggestion: true, HostTrack: true, countries: true, @@ -446,7 +452,9 @@ export class HostService { panNumber: companyData.panNumber, gstNumber: companyData.gstNumber || null, formationDate: companyData.formationDate ? new Date(companyData.formationDate as any) : null, - companyType: companyData.companyType, + companyTypes: companyData.companyTypeXid + ? { connect: { id: companyData.companyTypeXid } } + : undefined, websiteUrl: companyData.websiteUrl || null, instagramUrl: companyData.instagramUrl || null, facebookUrl: companyData.facebookUrl || null, @@ -475,13 +483,19 @@ export class HostService { if (companyData.isSubsidairy && parentCompanyData) { const createdParent = await tx.hostParent.create({ data: { - hostXid: createdHost.id, + host: { connect: { id: createdHost.id } }, companyName: parentCompanyData.companyName, address1: parentCompanyData.address1 || null, address2: parentCompanyData.address2 || null, - cityXid: parentCompanyData.cityXid || null, - stateXid: parentCompanyData.stateXid || null, - countryXid: parentCompanyData.countryXid || 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, isSubsidairy: false, @@ -489,7 +503,9 @@ export class HostService { panNumber: parentCompanyData.panNumber || null, gstNumber: parentCompanyData.gstNumber || null, formationDate: parentCompanyData.formationDate ? new Date(parentCompanyData.formationDate as any) : null, - companyType: parentCompanyData.companyType || null, + companyTypes: parentCompanyData.companyTypeXid + ? { connect: { id: parentCompanyData.companyTypeXid } } + : undefined, websiteUrl: parentCompanyData.websiteUrl || null, instagramUrl: parentCompanyData.instagramUrl || null, facebookUrl: parentCompanyData.facebookUrl || null, @@ -529,7 +545,9 @@ export class HostService { panNumber: companyData.panNumber, gstNumber: companyData.gstNumber || null, formationDate: companyData.formationDate ? new Date(companyData.formationDate as any) : null, - companyType: companyData.companyType, + companyTypes: companyData.companyTypeXid + ? { connect: { id: companyData.companyTypeXid } } + : undefined, websiteUrl: companyData.websiteUrl || null, instagramUrl: companyData.instagramUrl || null, facebookUrl: companyData.facebookUrl || null, @@ -584,13 +602,19 @@ export class HostService { // create const createdParent = await tx.hostParent.create({ data: { - hostXid: updatedHost.id, + host: { connect: { id: updatedHost.id } }, companyName: parentCompanyData.companyName, address1: parentCompanyData.address1 || null, address2: parentCompanyData.address2 || null, - cityXid: parentCompanyData.cityXid || null, - stateXid: parentCompanyData.stateXid || null, - countryXid: parentCompanyData.countryXid || 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, isSubsidairy: false, @@ -598,7 +622,9 @@ export class HostService { panNumber: parentCompanyData.panNumber || null, gstNumber: parentCompanyData.gstNumber || null, formationDate: parentCompanyData.formationDate ? new Date(parentCompanyData.formationDate as any) : null, - companyType: parentCompanyData.companyType || null, + companyTypes: parentCompanyData.companyTypeXid + ? { connect: { id: parentCompanyData.companyTypeXid } } + : undefined, websiteUrl: parentCompanyData.websiteUrl || null, instagramUrl: parentCompanyData.instagramUrl || null, facebookUrl: parentCompanyData.facebookUrl || null, @@ -627,16 +653,24 @@ export class HostService { companyName: parentCompanyData.companyName, address1: parentCompanyData.address1 || null, address2: parentCompanyData.address2 || null, - cityXid: parentCompanyData.cityXid || null, - stateXid: parentCompanyData.stateXid || null, - countryXid: parentCompanyData.countryXid || 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, - companyType: parentCompanyData.companyType || null, + companyTypes: parentCompanyData.companyTypeXid + ? { connect: { id: parentCompanyData.companyTypeXid } } + : undefined, websiteUrl: parentCompanyData.websiteUrl || null, instagramUrl: parentCompanyData.instagramUrl || null, facebookUrl: parentCompanyData.facebookUrl || null, diff --git a/src/modules/minglaradmin/services/minglar.service.ts b/src/modules/minglaradmin/services/minglar.service.ts index 7342bb4..d96ff5a 100644 --- a/src/modules/minglaradmin/services/minglar.service.ts +++ b/src/modules/minglaradmin/services/minglar.service.ts @@ -831,6 +831,12 @@ export class MinglarService { profileImage: true, }, }, + companyTypes: { + select: { + id: true, + companyTypeName: true, + }, + }, }, }); @@ -902,6 +908,12 @@ export class MinglarService { profileImage: true, }, }, + companyTypes: { + select: { + id: true, + companyTypeName: true, + }, + }, }, }); @@ -1435,6 +1447,12 @@ export class MinglarService { documentType: true, }, }, + companyTypes: { + select: { + id: true, + companyTypeName: true, + }, + }, user: { select: { id: true, diff --git a/src/modules/prepopulate/services/prepopulate.service.ts b/src/modules/prepopulate/services/prepopulate.service.ts index f233514..7960a33 100644 --- a/src/modules/prepopulate/services/prepopulate.service.ts +++ b/src/modules/prepopulate/services/prepopulate.service.ts @@ -37,8 +37,8 @@ export class PrePopulateService { } }); } - - + + async getCityByStateId(stateXid: number) { return await this.prisma.cities.findMany({ where: { @@ -90,7 +90,7 @@ export class PrePopulateService { } async getAllDocumentTypeWithCountryStateCity() { - const [documentDetails, countryDetails, stateDetails] = + const [documentDetails, countryDetails, stateDetails, companyTypeDetails] = await this.prisma.$transaction([ this.prisma.documentType.findMany({ where: { isActive: true, isVisible: true }, @@ -101,10 +101,15 @@ export class PrePopulateService { }), this.prisma.states.findMany({ where: { isActive: true }, + orderBy: { stateName: 'asc' } + }), + this.prisma.companyTypes.findMany({ + where: { isActive: true }, + orderBy: { companyTypeName: 'asc' } }), ]); - return { documentDetails, countryDetails, stateDetails }; + return { documentDetails, countryDetails, stateDetails, companyTypeDetails }; } async getAllFrequencies() {