allowed entry type

This commit is contained in:
paritosh18
2025-12-24 15:11:37 +05:30
parent 6440fc2440
commit 9b3fcd8cbe
2 changed files with 129 additions and 91 deletions

View File

@@ -2,8 +2,8 @@ import { z } from 'zod';
/* ================= MEDIA ================= */
export const MediaDto = z.object({
mediaType: z.string().optional(), // "image/jpeg", "video/mp4", etc.
mediaFileName: z.string(), // S3 file URL
mediaType: z.string().optional(), // "image/jpeg", "video/mp4", etc.
mediaFileName: z.string(), // S3 file URL
});
/* ================= PRICE =================
@@ -143,8 +143,8 @@ export const CreateActivityDto = z.object({
taxXids: z.array(z.number().int()).optional().default([]),
/* 🔥 MEDIA ARRAYS */
media: z.array(MediaDto).optional().default([]), // Activity-level media
venues: z.array(VenueDto).optional().default([]), // Each venues media + prices
media: z.array(MediaDto).optional().default([]), // Activity-level media
venues: z.array(VenueDto).optional().default([]), // Each venues media + prices
/* RELATION ARRAYS */
foodTypeIds: z.array(z.number().int()).optional().default([]),
@@ -157,6 +157,8 @@ export const CreateActivityDto = z.object({
/* EXTRA OBJECTS */
eligibility: EligibilityDto.optional(),
otherDetails: OtherDetailsDto.optional(),
allowedEntryTypes: z.array(z.number().int()).optional().default([]),
});
export type CreateActivityInput = z.infer<typeof CreateActivityDto>;

View File

@@ -1,4 +1,3 @@
// src/modules/host/services/host.service.ts
import { Injectable } from '@nestjs/common';
import {
@@ -106,7 +105,7 @@ const bucket = config.aws.bucketName;
@Injectable()
export class HostService {
constructor(private prisma: PrismaClient) { }
constructor(private prisma: PrismaClient) {}
async createHost(data: CreateHostDto) {
return this.prisma.user.create({ data });
@@ -761,7 +760,7 @@ export class HostService {
if (
existingHostCompany &&
existingHostCompany.hostStatusInternal ===
HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
!isDraft
) {
hostStatusInternal = HOST_STATUS_INTERNAL.HOST_SUBMITTED;
@@ -774,7 +773,7 @@ export class HostService {
else if (
existingHostCompany &&
existingHostCompany.hostStatusInternal ===
HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
HOST_STATUS_INTERNAL.HOST_TO_UPDATE &&
isDraft
) {
// keep original
@@ -885,19 +884,19 @@ export class HostService {
// Safely handle city connection - only connect if valid ID exists
cities:
parentCompanyData?.cityXid &&
!isNaN(Number(parentCompanyData.cityXid))
!isNaN(Number(parentCompanyData.cityXid))
? { connect: { id: Number(parentCompanyData.cityXid) } }
: undefined,
states:
parentCompanyData?.stateXid &&
!isNaN(Number(parentCompanyData.stateXid))
!isNaN(Number(parentCompanyData.stateXid))
? { connect: { id: Number(parentCompanyData.stateXid) } }
: undefined,
countries:
parentCompanyData?.countryXid &&
!isNaN(Number(parentCompanyData.countryXid))
!isNaN(Number(parentCompanyData.countryXid))
? { connect: { id: Number(parentCompanyData.countryXid) } }
: undefined,
pinCode: parentCompanyData.pinCode || null,
@@ -1047,19 +1046,19 @@ export class HostService {
address2: parentCompanyData.address2 || null,
cities:
parentCompanyData?.cityXid &&
!isNaN(Number(parentCompanyData.cityXid))
!isNaN(Number(parentCompanyData.cityXid))
? { connect: { id: Number(parentCompanyData.cityXid) } }
: undefined,
states:
parentCompanyData?.stateXid &&
!isNaN(Number(parentCompanyData.stateXid))
!isNaN(Number(parentCompanyData.stateXid))
? { connect: { id: Number(parentCompanyData.stateXid) } }
: undefined,
countries:
parentCompanyData?.countryXid &&
!isNaN(Number(parentCompanyData.countryXid))
!isNaN(Number(parentCompanyData.countryXid))
? { connect: { id: Number(parentCompanyData.countryXid) } }
: undefined,
pinCode: parentCompanyData.pinCode || null,
@@ -1105,19 +1104,19 @@ export class HostService {
address2: parentCompanyData.address2 || null,
cities:
parentCompanyData?.cityXid &&
!isNaN(Number(parentCompanyData.cityXid))
!isNaN(Number(parentCompanyData.cityXid))
? { connect: { id: Number(parentCompanyData.cityXid) } }
: undefined,
states:
parentCompanyData?.stateXid &&
!isNaN(Number(parentCompanyData.stateXid))
!isNaN(Number(parentCompanyData.stateXid))
? { connect: { id: Number(parentCompanyData.stateXid) } }
: undefined,
countries:
parentCompanyData?.countryXid &&
!isNaN(Number(parentCompanyData.countryXid))
!isNaN(Number(parentCompanyData.countryXid))
? { connect: { id: Number(parentCompanyData.countryXid) } }
: undefined,
pinCode: parentCompanyData.pinCode || null,
@@ -1726,21 +1725,21 @@ export class HostService {
select: {
id: true,
activityTypeName: true,
}
},
},
ActivitiesMedia: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
mediaType: true,
mediaFileName: true,
}
},
},
ActivityVenues: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
@@ -1755,10 +1754,10 @@ export class HostService {
select: {
id: true,
mediaType: true,
mediaFileName: true
}
}
}
mediaFileName: true,
},
},
},
},
ActivityPickUpDetails: {
where: {
@@ -1766,9 +1765,9 @@ export class HostService {
activityPickUpTransport: {
isActive: true,
transportMode: {
isActive: true
}
}
isActive: true,
},
},
},
select: {
id: true,
@@ -1787,12 +1786,12 @@ export class HostService {
transportMode: {
select: {
transportModeName: true,
transportModeIcon: true
}
}
}
}
}
transportModeIcon: true,
},
},
},
},
},
},
foodAvailable: true,
foodIsChargeable: true,
@@ -1803,40 +1802,40 @@ export class HostService {
foodType: {
select: {
id: true,
foodTypeName: true
}
foodTypeName: true,
},
},
}
},
},
activityCuisines: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
foodCuisine: {
select: {
id: true,
cuisineName: true
}
}
}
cuisineName: true,
},
},
},
},
alcoholAvailable: true,
trainerAvailable: true,
trainerIsChargeable: true,
ActivityTrainers: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
totalAmount: true
}
totalAmount: true,
},
},
ActivityNavigationModes: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
@@ -1846,27 +1845,27 @@ export class HostService {
select: {
id: true,
navigationModeName: true,
navigationModeIcon: true
}
}
}
navigationModeIcon: true,
},
},
},
},
equipmentAvailable: true,
equipmentIsChargeable: true,
ActivityEquipments: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
equipmentName: true,
isEquipmentChargeable: true,
equipmentTotalPrice: true,
}
},
},
ActivityOtherDetails: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
@@ -1875,22 +1874,22 @@ export class HostService {
dontsNotes: true,
tipsNotes: true,
termsAndCondition: true,
}
},
},
energyLevel: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
energyLevelName: true,
energyIcon: true,
energyColor: true
}
energyColor: true,
},
},
ActivityEligibility: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
@@ -1901,7 +1900,7 @@ export class HostService {
ageRestrictionName: true,
minAge: true,
maxAge: true,
}
},
},
isWeightRestriction: true,
weightRestrictionName: true,
@@ -1914,39 +1913,39 @@ export class HostService {
heightEntered: true,
heightIn: true,
minHeight: true,
maxHeight: true
}
maxHeight: true,
},
},
ActivityAllowedEntry: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
allowedEntryType: {
select: {
id: true,
allowedEntryTypeName: true
}
}
}
allowedEntryTypeName: true,
},
},
},
},
ActivityAmenities: {
where: {
isActive: true
isActive: true,
},
select: {
id: true,
amenities: {
select: {
id: true,
amenitiesName: true
}
}
}
amenitiesName: true,
},
},
},
},
cancellationAvailable: true,
cancellationAllowedBeforeMins: true
cancellationAllowedBeforeMins: true,
// accountManager: {
// select: {
// id: true,
@@ -1965,9 +1964,8 @@ export class HostService {
// adminStatusInternal: true,
// }
// }
}
})
},
});
if (!activity) {
throw new ApiError(404, 'Activity not found');
@@ -2280,11 +2278,7 @@ export class HostService {
* ActivityPickUpTransport/Details + ActivityNavigationModes + ActivityEquipments +
* ActivityAmenities + ActivityEligibility
*/
async createOrUpdateActivity(
userId: number,
payload: any,
isDraft: boolean,
) {
async createOrUpdateActivity(userId: number, payload: any, isDraft: boolean) {
/* =====================================================
* HELPERS
* ===================================================== */
@@ -2363,7 +2357,10 @@ export class HostService {
}
if (v.isMinPeopleReqMandatory && !v.minPeopleRequired) {
throw new ApiError(400, `venues[${idx}] min people requirement missing`);
throw new ApiError(
400,
`venues[${idx}] min people requirement missing`,
);
}
if (!Array.isArray(v.prices) || !v.prices.length) {
@@ -2381,9 +2378,9 @@ export class HostService {
const rootTaxes =
taxIds.length > 0
? await this.prisma.taxes.findMany({
where: { id: { in: taxIds }, isActive: true },
select: { id: true, taxPer: true },
})
where: { id: { in: taxIds }, isActive: true },
select: { id: true, taxPer: true },
})
: [];
if (taxIds.length !== rootTaxes.length) {
@@ -2604,7 +2601,8 @@ export class HostService {
noOfSession: price.noOfSession ?? 1,
isPackage: price.isPackage ?? false,
sessionValidity: price.sessionValidity ?? 0,
sessionValidityFrequency: price.sessionValidityFrequency ?? 'Days',
sessionValidityFrequency:
price.sessionValidityFrequency ?? 'Days',
basePrice,
sellPrice,
},
@@ -2843,7 +2841,9 @@ export class HostService {
data: {
activityXid,
navigationModeXid: modeId,
isInActivityChargeable: toBool(payload.navigationModeIsChargeable),
isInActivityChargeable: toBool(
payload.navigationModeIsChargeable,
),
navigationModesBasePrice: basePrice,
navigationModesTotalPrice: totalPrice,
},
@@ -2887,14 +2887,20 @@ export class HostService {
activityXid,
isAgeRestriction: toBool(payload.eligibility.isAgeRestriction),
ageRestrictionXid: toNumber(payload.eligibility.ageRestrictionXid),
isWeightRestriction: toBool(payload.eligibility.isWeightRestriction),
weightRestrictionName: payload.eligibility.weightRestrictionName ?? null,
isWeightRestriction: toBool(
payload.eligibility.isWeightRestriction,
),
weightRestrictionName:
payload.eligibility.weightRestrictionName ?? null,
weightEntered: toNumber(payload.eligibility.weightEntered),
weightIn: payload.eligibility.weightIn ?? null,
minWeight: toNumber(payload.eligibility.minWeight),
maxWeight: toNumber(payload.eligibility.maxWeight),
isHeightRestriction: toBool(payload.eligibility.isHeightRestriction),
heightRestrictionName: payload.eligibility.heightRestrictionName ?? null,
isHeightRestriction: toBool(
payload.eligibility.isHeightRestriction,
),
heightRestrictionName:
payload.eligibility.heightRestrictionName ?? null,
heightEntered: toNumber(payload.eligibility.heightEntered),
heightIn: payload.eligibility.heightIn ?? null,
minHeight: toNumber(payload.eligibility.minHeight),
@@ -2949,6 +2955,33 @@ export class HostService {
});
}
const allowedEntryIds = Array.isArray(payload.allowedEntryTypes)
? payload.allowedEntryTypes.map(Number)
: [];
if (allowedEntryIds.length) {
const validEntryTypes = await this.prisma.allowedEntryTypes.findMany({
where: { id: { in: allowedEntryIds }, isActive: true },
select: { id: true },
});
if (validEntryTypes.length !== allowedEntryIds.length)
throw new ApiError(
400,
'Invalid or inactive allowed entry type(s) provided',
);
}
/* --------------------------------
* CLEAN & CREATE ALLOWED ENTRY
* -------------------------------- */
await tx.activityAllowedEntry.deleteMany({ where: { activityXid } });
if (allowedEntryIds.length) {
await tx.activityAllowedEntry.createMany({
data: allowedEntryIds.map((entryId) => ({
activityXid,
allowedEntryTypeXid: entryId,
})),
});
}
/* --------------------------------
* 1⃣8⃣ ACTIVITY TRACK
* -------------------------------- */
@@ -2969,10 +3002,13 @@ export class HostService {
return {
activityXid,
activityRefNumber: activity.activityRefNumber,
status: isDraft ? ACTIVITY_INTERNAL_STATUS.ACTIVITY_DRAFT : ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED,
status: isDraft
? ACTIVITY_INTERNAL_STATUS.ACTIVITY_DRAFT
: ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED,
};
});
}
async getAllPQUpdatedResponse(activityXid: number) {
const pqqHeaderData = await this.prisma.activityPQQheader.findMany({
where: {