diff --git a/serverless/functions/host.yml b/serverless/functions/host.yml
index 2b1d8f9..4b27789 100644
--- a/serverless/functions/host.yml
+++ b/serverless/functions/host.yml
@@ -307,7 +307,6 @@ updatePQQ_LastAnswer:
path: /host/Activity_Hub/OnBoarding/submit-final-pqq-answer
method: post
-
submitPQQForReview:
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQQForReview.handler
memorySize: 384
@@ -339,6 +338,21 @@ getAllPQQwithSubmittedAns:
path: /host/Activity_Hub/OnBoarding/get-all-pqq-ques-submited-ans
method: get
+getAllDetailsOfActivityAndVenue:
+ handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getAllDetailsOfActivityAndVenue.handler
+ memorySize: 512
+ package:
+ patterns:
+ - 'src/modules/host/handlers/Activity_Hub/OnBoarding/**'
+ - ${file(./serverless/patterns/base.yml):pattern1}
+ - ${file(./serverless/patterns/base.yml):pattern2}
+ - ${file(./serverless/patterns/base.yml):pattern3}
+ - ${file(./serverless/patterns/base.yml):pattern4}
+ events:
+ - httpApi:
+ path: /host/Activity_Hub/OnBoarding/get-all-details-activity-venue/{activityXid}
+ method: get
+
updateSuggestionAsReviewed:
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/updateSuggestionAsReviewed.handler
memorySize: 512
diff --git a/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllActivityType.ts b/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllActivityType.ts
index e6839d0..ffab71c 100644
--- a/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllActivityType.ts
+++ b/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllActivityType.ts
@@ -25,7 +25,7 @@ export const handler = safeHandler(async (
}
// Verify token and get user info
- const userInfo = await verifyHostToken(token);
+ await verifyHostToken(token);
// Read optional search query (supports ?search= or ?q=)
diff --git a/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllDetailsOfActivityAndVenue.ts b/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllDetailsOfActivityAndVenue.ts
new file mode 100644
index 0000000..a8e72ae
--- /dev/null
+++ b/src/modules/host/handlers/Activity_Hub/OnBoarding/getAllDetailsOfActivityAndVenue.ts
@@ -0,0 +1,47 @@
+import { verifyMinglarAdminHostToken } from '../../../../../common/middlewares/jwt/authForMinglarAdminHost';
+import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
+import { prismaClient } from '../../../../../common/database/prisma.lambda.service';
+import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
+import ApiError from '../../../../../common/utils/helper/ApiError';
+import { HostService } from '../../../services/host.service';
+
+const hostService = new HostService(prismaClient);
+
+/**
+ * Add suggestion handler for host applications
+ * Allows Minglar Admin, Co_Admin, and Account Manager to add suggestions
+ * Types: Setup Profile, Review Account, Add Payment Details, Agreement
+ */
+export const handler = safeHandler(async (
+ event: APIGatewayProxyEvent,
+ context?: Context
+): Promise => {
+ // Verify authentication token
+ const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
+ if (!token) {
+ throw new ApiError(401, 'This is a protected route. Please provide a valid token.');
+ }
+
+ // Verify token and get user info
+ await verifyMinglarAdminHostToken(token);
+
+ const activityXid = event.pathParameters?.activityXid
+ if (!activityXid) {
+ throw new ApiError(400, 'activityXid is required in path parameters');
+ }
+
+ const data = await hostService.getAllDetailsOfActivityAndVenue(Number(activityXid));
+
+ return {
+ statusCode: 200,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Access-Control-Allow-Origin': '*',
+ },
+ body: JSON.stringify({
+ success: true,
+ message: 'Data retrieved successfully',
+ data,
+ }),
+ };
+});
diff --git a/src/modules/host/services/host.service.ts b/src/modules/host/services/host.service.ts
index 9a68f9a..622bd41 100644
--- a/src/modules/host/services/host.service.ts
+++ b/src/modules/host/services/host.service.ts
@@ -106,7 +106,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 +761,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 +774,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 +885,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 +1047,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 +1105,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,
@@ -1703,6 +1703,241 @@ export class HostService {
});
}
+ async getAllDetailsOfActivityAndVenue(activityXid: number) {
+ return await this.prisma.activities.findMany({
+ where: { id: activityXid, isActive: true },
+ select: {
+ id: true,
+ activityTitle: true,
+ activityDescription: true,
+ activityDisplayStatus: true,
+ activityInternalStatus: true,
+ activityRefNumber: true,
+ checkInAddress: true,
+ checkInLat: true,
+ checkInLong: true,
+ checkOutAddress: true,
+ checkOutLat: true,
+ checkOutLong: true,
+ pickUpDropAvailable: true,
+ pickUpDropIsChargeable: true,
+ activityDurationMins: true,
+ activityType: {
+ select: {
+ id: true,
+ activityTypeName: true,
+ }
+ },
+ ActivityPickUpDetails: {
+ where: {
+ isActive: true,
+ activityPickUpTransport: {
+ isActive: true,
+ transportMode: {
+ isActive: true
+ }
+ }
+ },
+ select: {
+ id: true,
+ isPickUp: true,
+ locationAddress: true,
+ locationLat: true,
+ locationLong: true,
+ transportTotalPrice: true,
+ transportBasePrice: true,
+
+ activityPickUpTransport: {
+ select: {
+ id: true,
+ isTransportModeChargeable: true,
+
+ transportMode: {
+ select: {
+ transportModeName: true,
+ transportModeIcon: true
+ }
+ }
+ }
+ }
+ }
+ },
+ foodAvailable: true,
+ foodIsChargeable: true,
+ activityFoodTypes: {
+ where: { isActive: true },
+ select: {
+ id: true,
+ foodType: {
+ select: {
+ id: true,
+ foodTypeName: true
+ }
+ },
+ }
+ },
+ activityCuisines: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ foodCuisine: {
+ select: {
+ id: true,
+ cuisineName: true
+ }
+ }
+ }
+ },
+ alcoholAvailable: true,
+ trainerAvailable: true,
+ trainerIsChargeable: true,
+ ActivityTrainers: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ totalAmount: true
+ }
+ },
+ ActivityNavigationModes: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ isInActivityChargeable: true,
+ navigationModesTotalPrice: true,
+ navigationMode: {
+ select: {
+ id: true,
+ navigationModeName: true,
+ navigationModeIcon: true
+ }
+ }
+ }
+ },
+ equipmentAvailable: true,
+ equipmentIsChargeable: true,
+ ActivityEquipments: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ equipmentName: true,
+ isEquipmentChargeable: true,
+ equipmentTotalPrice: true,
+ }
+ },
+ ActivityOtherDetails: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ exclusiveNotes: true,
+ dosNotes: true,
+ dontsNotes: true,
+ tipsNotes: true,
+ termsAndCondition: true,
+ }
+ },
+ energyLevel: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ energyLevelName: true,
+ energyIcon: true,
+ energyColor: true
+ }
+ },
+ ActivityEligibility: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ isAgeRestriction: true,
+ ageRestriction: {
+ select: {
+ id: true,
+ ageRestrictionName: true,
+ minAge: true,
+ maxAge: true,
+ }
+ },
+ isWeightRestriction: true,
+ weightRestrictionName: true,
+ weightEntered: true,
+ weightIn: true,
+ minWeight: true,
+ maxWeight: true,
+ isHeightRestriction: true,
+ heightRestrictionName: true,
+ heightEntered: true,
+ heightIn: true,
+ minHeight: true,
+ maxHeight: true
+ }
+ },
+ ActivityAllowedEntry: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ allowedEntryType: {
+ select: {
+ id: true,
+ allowedEntryTypeName: true
+ }
+ }
+ }
+ },
+ ActivityAmenities: {
+ where: {
+ isActive: true
+ },
+ select: {
+ id: true,
+ amenities: {
+ select: {
+ id: true,
+ amenitiesName: true
+ }
+ }
+ }
+ },
+ cancellationAvailable: true,
+ cancellationAllowedBeforeMins: true
+ // accountManager: {
+ // select: {
+ // id: true,
+ // firstName: true,
+ // lastName: true,
+ // emailAddress: true,
+ // mobileNumber: true,
+ // }
+ // },
+ // host: {
+ // select: {
+ // id: true,
+ // companyName: true,
+ // stepper: true,
+ // adminStatusDisplay: true,
+ // adminStatusInternal: true,
+ // }
+ // }
+
+ }
+ })
+ }
+
async createActivity(
userId: number,
activityTypeXid: number,
@@ -1973,340 +2208,436 @@ export class HostService {
* ActivityPickUpTransport/Details + ActivityNavigationModes + ActivityEquipments +
* ActivityAmenities + ActivityEligibility
*/
-async createOrUpdateActivity(
- userId: number,
- payload: any,
- isDraft: boolean,
-) {
- /* =====================================================
- * HELPERS
- * ===================================================== */
- const toBool = (v: any) =>
- v === true || v === 'true' || v === 1 || v === '1';
+ async createOrUpdateActivity(
+ userId: number,
+ payload: any,
+ isDraft: boolean,
+ ) {
+ /* =====================================================
+ * HELPERS
+ * ===================================================== */
+ const toBool = (v: any) =>
+ v === true || v === 'true' || v === 1 || v === '1';
- const toNumber = (v: any) =>
- v === undefined || v === null || v === '' ? undefined : Number(v);
+ const toNumber = (v: any) =>
+ v === undefined || v === null || v === '' ? undefined : Number(v);
- const round2 = (v: number) => Math.round(v);
+ const round2 = (v: number) => Math.round(v);
- const computeBasePriceAndTaxes = (
- sellPrice: number,
- taxes: Array<{ id: number; taxPer: number }>,
- ) => {
- if (!taxes.length) {
- return { basePrice: round2(sellPrice), taxDetails: [] };
- }
+ const computeBasePriceAndTaxes = (
+ sellPrice: number,
+ taxes: Array<{ id: number; taxPer: number }>,
+ ) => {
+ if (!taxes.length) {
+ return { basePrice: round2(sellPrice), taxDetails: [] };
+ }
- const totalTaxPer = taxes.reduce((s, t) => s + Number(t.taxPer || 0), 0);
- const basePrice = round2(sellPrice / (1 + totalTaxPer / 100));
+ const totalTaxPer = taxes.reduce((s, t) => s + Number(t.taxPer || 0), 0);
+ const basePrice = round2(sellPrice / (1 + totalTaxPer / 100));
- return {
- basePrice,
- taxDetails: taxes.map((t) => ({
- taxXid: t.id,
- taxPer: t.taxPer,
- taxAmount: round2(basePrice * (t.taxPer / 100)),
- })),
+ return {
+ basePrice,
+ taxDetails: taxes.map((t) => ({
+ taxXid: t.id,
+ taxPer: t.taxPer,
+ taxAmount: round2(basePrice * (t.taxPer / 100)),
+ })),
+ };
};
- };
- /* =====================================================
- * BASIC GUARDS
- * ===================================================== */
- if (!payload.activityXid) {
- throw new ApiError(400, 'activityXid is required');
- }
-
- /* =====================================================
- * HARD NORMALIZATION (SERVICE-LEVEL)
- * ===================================================== */
- payload.foodAvailable = toBool(payload.foodAvailable);
- payload.alcoholAvailable = toBool(payload.alcoholAvailable);
- payload.trainerAvailable = toBool(payload.trainerAvailable);
- payload.pickUpDropAvailable = toBool(payload.pickUpDropAvailable);
- payload.inActivityAvailable = toBool(payload.inActivityAvailable);
- payload.equipmentAvailable = toBool(payload.equipmentAvailable);
- payload.cancellationAvailable = toBool(payload.cancellationAvailable);
- payload.isInstantBooking = toBool(payload.isInstantBooking);
- payload.isCheckOutSame = toBool(payload.isCheckOutSame);
-
- payload.trainerTotalAmount = toNumber(payload.trainerTotalAmount);
-
- if (payload.trainerAvailable) {
- if (
- typeof payload.trainerTotalAmount !== 'number' ||
- Number.isNaN(payload.trainerTotalAmount) ||
- payload.trainerTotalAmount <= 0
- ) {
- throw new ApiError(400, 'trainerTotalAmount must be > 0');
- }
- } else {
- delete payload.trainerTotalAmount;
- }
-
- if (payload.venues && !Array.isArray(payload.venues)) {
- throw new ApiError(400, 'venues must be an array');
- }
-
- payload.venues?.forEach((v, idx) => {
- v.isMinPeopleReqMandatory = toBool(v.isMinPeopleReqMandatory);
-
- if (!v.venueName) {
- throw new ApiError(400, `venues[${idx}] venueName required`);
+ /* =====================================================
+ * BASIC GUARDS
+ * ===================================================== */
+ if (!payload.activityXid) {
+ throw new ApiError(400, 'activityXid is required');
}
- if (v.isMinPeopleReqMandatory && !v.minPeopleRequired) {
- throw new ApiError(400, `venues[${idx}] min people requirement missing`);
+ /* =====================================================
+ * HARD NORMALIZATION (SERVICE-LEVEL)
+ * ===================================================== */
+ payload.foodAvailable = toBool(payload.foodAvailable);
+ payload.alcoholAvailable = toBool(payload.alcoholAvailable);
+ payload.trainerAvailable = toBool(payload.trainerAvailable);
+ payload.pickUpDropAvailable = toBool(payload.pickUpDropAvailable);
+ payload.inActivityAvailable = toBool(payload.inActivityAvailable);
+ payload.equipmentAvailable = toBool(payload.equipmentAvailable);
+ payload.cancellationAvailable = toBool(payload.cancellationAvailable);
+ payload.isInstantBooking = toBool(payload.isInstantBooking);
+ payload.isCheckOutSame = toBool(payload.isCheckOutSame);
+
+ payload.trainerTotalAmount = toNumber(payload.trainerTotalAmount);
+
+ if (payload.trainerAvailable) {
+ if (
+ typeof payload.trainerTotalAmount !== 'number' ||
+ Number.isNaN(payload.trainerTotalAmount) ||
+ payload.trainerTotalAmount <= 0
+ ) {
+ throw new ApiError(400, 'trainerTotalAmount must be > 0');
+ }
+ } else {
+ delete payload.trainerTotalAmount;
}
- if (!Array.isArray(v.prices) || !v.prices.length) {
- throw new ApiError(400, `venues[${idx}] must have at least one price`);
+ if (payload.venues && !Array.isArray(payload.venues)) {
+ throw new ApiError(400, 'venues must be an array');
}
- });
- /* =====================================================
- * ROOT TAX
- * ===================================================== */
- const taxIds = Array.isArray(payload.taxXids)
- ? payload.taxXids.map(Number)
- : [];
+ payload.venues?.forEach((v, idx) => {
+ v.isMinPeopleReqMandatory = toBool(v.isMinPeopleReqMandatory);
- const rootTaxes =
- taxIds.length > 0
- ? await this.prisma.taxes.findMany({
+ if (!v.venueName) {
+ throw new ApiError(400, `venues[${idx}] venueName required`);
+ }
+
+ if (v.isMinPeopleReqMandatory && !v.minPeopleRequired) {
+ throw new ApiError(400, `venues[${idx}] min people requirement missing`);
+ }
+
+ if (!Array.isArray(v.prices) || !v.prices.length) {
+ throw new ApiError(400, `venues[${idx}] must have at least one price`);
+ }
+ });
+
+ /* =====================================================
+ * ROOT TAX
+ * ===================================================== */
+ const taxIds = Array.isArray(payload.taxXids)
+ ? payload.taxXids.map(Number)
+ : [];
+
+ const rootTaxes =
+ taxIds.length > 0
+ ? await this.prisma.taxes.findMany({
where: { id: { in: taxIds }, isActive: true },
select: { id: true, taxPer: true },
})
- : [];
+ : [];
- if (taxIds.length !== rootTaxes.length) {
- throw new ApiError(400, 'Invalid or inactive tax provided');
- }
-
- /* =====================================================
- * TRANSACTION
- * ===================================================== */
- return await this.prisma.$transaction(async (tx) => {
- /* --------------------------------
- * 1️⃣ HOST
- * -------------------------------- */
- const host = await tx.hostHeader.findFirst({
- where: { userXid: userId, isActive: true },
- });
- if (!host) throw new ApiError(404, 'Host not found');
-
- /* --------------------------------
- * 2️⃣ ACTIVITY
- * -------------------------------- */
- const existingActivity = await tx.activities.findFirst({
- where: {
- id: Number(payload.activityXid),
- hostXid: host.id,
- isActive: true,
- },
- });
- if (!existingActivity) {
- throw new ApiError(404, 'Activity not found');
+ if (taxIds.length !== rootTaxes.length) {
+ throw new ApiError(400, 'Invalid or inactive tax provided');
}
- /* --------------------------------
- * 3️⃣ STATUS DECISION
- * -------------------------------- */
- let activityInternalStatus;
- let activityDisplayStatus;
- let amInternalStatus;
- let amDisplayStatus;
+ /* =====================================================
+ * TRANSACTION
+ * ===================================================== */
+ return await this.prisma.$transaction(async (tx) => {
+ /* --------------------------------
+ * 1️⃣ HOST
+ * -------------------------------- */
+ const host = await tx.hostHeader.findFirst({
+ where: { userXid: userId, isActive: true },
+ });
+ if (!host) throw new ApiError(404, 'Host not found');
- const wasRejected =
- existingActivity.activityInternalStatus ===
- ACTIVITY_INTERNAL_STATUS.ACTIVITY_REJECTED;
+ /* --------------------------------
+ * 2️⃣ ACTIVITY
+ * -------------------------------- */
+ const existingActivity = await tx.activities.findFirst({
+ where: {
+ id: Number(payload.activityXid),
+ hostXid: host.id,
+ isActive: true,
+ },
+ });
+ if (!existingActivity) {
+ throw new ApiError(404, 'Activity not found');
+ }
- if (wasRejected) {
- if (isDraft) {
- activityInternalStatus = existingActivity.activityInternalStatus;
- activityDisplayStatus = existingActivity.activityDisplayStatus;
- amInternalStatus = existingActivity.amInternalStatus;
- amDisplayStatus = existingActivity.amDisplayStatus;
+ /* --------------------------------
+ * 3️⃣ STATUS DECISION
+ * -------------------------------- */
+ let activityInternalStatus;
+ let activityDisplayStatus;
+ let amInternalStatus;
+ let amDisplayStatus;
+
+ const wasRejected =
+ existingActivity.activityInternalStatus ===
+ ACTIVITY_INTERNAL_STATUS.ACTIVITY_REJECTED;
+
+ if (wasRejected) {
+ if (isDraft) {
+ activityInternalStatus = existingActivity.activityInternalStatus;
+ activityDisplayStatus = existingActivity.activityDisplayStatus;
+ amInternalStatus = existingActivity.amInternalStatus;
+ amDisplayStatus = existingActivity.amDisplayStatus;
+ } else {
+ activityInternalStatus = ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED;
+ activityDisplayStatus = ACTIVITY_DISPLAY_STATUS.ACTIVITY_IN_REVIEW;
+ amInternalStatus = ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_TO_REVIEW;
+ amDisplayStatus = ACTIVITY_AM_DISPLAY_STATUS.ACTIVITY_NEW;
+ }
} else {
- activityInternalStatus = ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED;
- activityDisplayStatus = ACTIVITY_DISPLAY_STATUS.ACTIVITY_IN_REVIEW;
- amInternalStatus = ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_TO_REVIEW;
- amDisplayStatus = ACTIVITY_AM_DISPLAY_STATUS.ACTIVITY_NEW;
- }
- } else {
- if (isDraft) {
- activityInternalStatus = ACTIVITY_INTERNAL_STATUS.ACTIVITY_DRAFT;
- activityDisplayStatus = ACTIVITY_DISPLAY_STATUS.ACTIVITY_DRAFT;
- amInternalStatus = ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_DRAFT;
- amDisplayStatus = ACTIVITY_AM_DISPLAY_STATUS.ACTIVITY_DRAFT;
- } else {
- activityInternalStatus = ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED;
- activityDisplayStatus = ACTIVITY_DISPLAY_STATUS.ACTIVITY_IN_REVIEW;
- amInternalStatus = ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_TO_REVIEW;
- amDisplayStatus = ACTIVITY_AM_DISPLAY_STATUS.ACTIVITY_NEW;
- }
- }
-
- /* --------------------------------
- * 4️⃣ UPDATE ACTIVITY CORE + FLAGS
- * -------------------------------- */
- const activity = await tx.activities.update({
- where: { id: existingActivity.id },
- data: {
- activityTypeXid: payload.activityTypeXid ?? undefined,
- frequenciesXid: payload.frequenciesXid ?? undefined,
- activityTitle: payload.activityTitle ?? undefined,
- activityDescription: payload.activityDescription ?? undefined,
-
- checkInLat: payload.checkInLat ?? undefined,
- checkInLong: payload.checkInLong ?? undefined,
- checkInAddress: payload.checkInAddress ?? undefined,
- isCheckOutSame: toBool(payload.isCheckOutSame),
- checkOutLat: payload.checkOutLat ?? undefined,
- checkOutLong: payload.checkOutLong ?? undefined,
- checkOutAddress: payload.checkOutAddress ?? undefined,
-
- energyLevelXid: payload.energyLevelXid ?? undefined,
- activityDurationMins: payload.activityDurationMins ?? undefined,
-
- currencyXid: payload.currencyXid ?? undefined,
- sustainabilityScore: payload.sustainabilityScore ?? undefined,
- safetyScore: payload.safetyScore ?? undefined,
- isInstantBooking: payload.isInstantBooking ?? undefined,
-
- foodAvailable: payload.foodAvailable,
- foodIsChargeable: toBool(payload.foodIsChargeable),
- alcoholAvailable: payload.alcoholAvailable,
- trainerAvailable: payload.trainerAvailable,
- trainerIsChargeable: toBool(payload.trainerIsChargeable),
- pickUpDropAvailable: payload.pickUpDropAvailable,
- pickUpDropIsChargeable: toBool(payload.pickUpDropIsChargeable),
- inActivityAvailable: payload.inActivityAvailable,
- inActivityIsChargeable: toBool(payload.inActivityIsChargeable),
- equipmentAvailable: payload.equipmentAvailable,
- equipmentIsChargeable: toBool(payload.equipmentIsChargeable),
- cancellationAvailable: payload.cancellationAvailable,
-
- activityInternalStatus,
- activityDisplayStatus,
- amInternalStatus,
- amDisplayStatus,
- },
- });
-
- const activityXid = activity.id;
-
- /* --------------------------------
- * 5️⃣ CLEAN OLD ACTIVITY MEDIA
- * -------------------------------- */
- await tx.activitiesMedia.deleteMany({ where: { activityXid } });
-
- /* --------------------------------
- * 6️⃣ SAVE NEW ACTIVITY MEDIA
- * -------------------------------- */
- if (Array.isArray(payload.media) && payload.media.length) {
- await tx.activitiesMedia.createMany({
- data: payload.media.map((m, index) => ({
- activityXid,
- mediaType: m.mediaType ?? 'unknown',
- mediaFileName: m.mediaFileName,
- displayOrder: index + 1,
- })),
- });
- }
-
- /* --------------------------------
- * 7️⃣ CLEAN OLD VENUES & RELATED DATA
- * -------------------------------- */
- const oldVenueIds = (
- await tx.activityVenues.findMany({
- where: { activityXid },
- select: { id: true },
- })
- ).map((v) => v.id);
-
- if (oldVenueIds.length) {
- // Clean venue artifacts (media)
- await tx.activityVenueArtifacts.deleteMany({
- where: { activityVenueXid: { in: oldVenueIds } },
- });
-
- // Clean price taxes and prices
- const priceIds = (
- await tx.activityPrices.findMany({
- where: { activityVenueXid: { in: oldVenueIds } },
- select: { id: true },
- })
- ).map((p) => p.id);
-
- if (priceIds.length) {
- await tx.activityPriceTaxes.deleteMany({
- where: { activityPriceXid: { in: priceIds } },
- });
- await tx.activityPrices.deleteMany({
- where: { id: { in: priceIds } },
- });
+ if (isDraft) {
+ activityInternalStatus = ACTIVITY_INTERNAL_STATUS.ACTIVITY_DRAFT;
+ activityDisplayStatus = ACTIVITY_DISPLAY_STATUS.ACTIVITY_DRAFT;
+ amInternalStatus = ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_DRAFT;
+ amDisplayStatus = ACTIVITY_AM_DISPLAY_STATUS.ACTIVITY_DRAFT;
+ } else {
+ activityInternalStatus = ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED;
+ activityDisplayStatus = ACTIVITY_DISPLAY_STATUS.ACTIVITY_IN_REVIEW;
+ amInternalStatus = ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_TO_REVIEW;
+ amDisplayStatus = ACTIVITY_AM_DISPLAY_STATUS.ACTIVITY_NEW;
+ }
}
- // Clean venues
- await tx.activityVenues.deleteMany({
- where: { id: { in: oldVenueIds } },
- });
- }
-
- /* --------------------------------
- * 8️⃣ CREATE VENUES WITH MEDIA & PRICES
- * -------------------------------- */
- for (const venue of payload.venues ?? []) {
- const venueRow = await tx.activityVenues.create({
+ /* --------------------------------
+ * 4️⃣ UPDATE ACTIVITY CORE + FLAGS
+ * -------------------------------- */
+ const activity = await tx.activities.update({
+ where: { id: existingActivity.id },
data: {
- activityXid,
- venueName: venue.venueName,
- venueCapacity: toNumber(venue.venueCapacity) ?? 0,
- availableSeats: toNumber(venue.availableSeats) ?? 0,
- isMinPeopleReqMandatory: venue.isMinPeopleReqMandatory,
- minPeopleRequired: toNumber(venue.minPeopleRequired) ?? null,
- minReqfullfilledBeforeMins:
- toNumber(venue.minReqfullfilledBeforeMins) ?? null,
- venueDescription: venue.venueDescription ?? null,
+ activityTypeXid: payload.activityTypeXid ?? undefined,
+ frequenciesXid: payload.frequenciesXid ?? undefined,
+ activityTitle: payload.activityTitle ?? undefined,
+ activityDescription: payload.activityDescription ?? undefined,
+
+ checkInLat: payload.checkInLat ?? undefined,
+ checkInLong: payload.checkInLong ?? undefined,
+ checkInAddress: payload.checkInAddress ?? undefined,
+ isCheckOutSame: toBool(payload.isCheckOutSame),
+ checkOutLat: payload.checkOutLat ?? undefined,
+ checkOutLong: payload.checkOutLong ?? undefined,
+ checkOutAddress: payload.checkOutAddress ?? undefined,
+
+ energyLevelXid: payload.energyLevelXid ?? undefined,
+ activityDurationMins: payload.activityDurationMins ?? undefined,
+
+ currencyXid: payload.currencyXid ?? undefined,
+ sustainabilityScore: payload.sustainabilityScore ?? undefined,
+ safetyScore: payload.safetyScore ?? undefined,
+ isInstantBooking: payload.isInstantBooking ?? undefined,
+
+ foodAvailable: payload.foodAvailable,
+ foodIsChargeable: toBool(payload.foodIsChargeable),
+ alcoholAvailable: payload.alcoholAvailable,
+ trainerAvailable: payload.trainerAvailable,
+ trainerIsChargeable: toBool(payload.trainerIsChargeable),
+ pickUpDropAvailable: payload.pickUpDropAvailable,
+ pickUpDropIsChargeable: toBool(payload.pickUpDropIsChargeable),
+ inActivityAvailable: payload.inActivityAvailable,
+ inActivityIsChargeable: toBool(payload.inActivityIsChargeable),
+ equipmentAvailable: payload.equipmentAvailable,
+ equipmentIsChargeable: toBool(payload.equipmentIsChargeable),
+ cancellationAvailable: payload.cancellationAvailable,
+
+ activityInternalStatus,
+ activityDisplayStatus,
+ amInternalStatus,
+ amDisplayStatus,
},
});
- // Create venue media/artifacts
- if (Array.isArray(venue.media) && venue.media.length) {
- await tx.activityVenueArtifacts.createMany({
- data: venue.media.map((m) => ({
- activityVenueXid: venueRow.id,
- mediaType: m.mediaType ?? 'image',
+ const activityXid = activity.id;
+
+ /* --------------------------------
+ * 5️⃣ CLEAN OLD ACTIVITY MEDIA
+ * -------------------------------- */
+ await tx.activitiesMedia.deleteMany({ where: { activityXid } });
+
+ /* --------------------------------
+ * 6️⃣ SAVE NEW ACTIVITY MEDIA
+ * -------------------------------- */
+ if (Array.isArray(payload.media) && payload.media.length) {
+ await tx.activitiesMedia.createMany({
+ data: payload.media.map((m, index) => ({
+ activityXid,
+ mediaType: m.mediaType ?? 'unknown',
mediaFileName: m.mediaFileName,
+ displayOrder: index + 1,
})),
});
}
- // Create venue prices with taxes
- for (const price of venue.prices ?? []) {
- const sellPrice = Number(price.sellPrice);
+ /* --------------------------------
+ * 7️⃣ CLEAN OLD VENUES & RELATED DATA
+ * -------------------------------- */
+ const oldVenueIds = (
+ await tx.activityVenues.findMany({
+ where: { activityXid },
+ select: { id: true },
+ })
+ ).map((v) => v.id);
+
+ if (oldVenueIds.length) {
+ // Clean venue artifacts (media)
+ await tx.activityVenueArtifacts.deleteMany({
+ where: { activityVenueXid: { in: oldVenueIds } },
+ });
+
+ // Clean price taxes and prices
+ const priceIds = (
+ await tx.activityPrices.findMany({
+ where: { activityVenueXid: { in: oldVenueIds } },
+ select: { id: true },
+ })
+ ).map((p) => p.id);
+
+ if (priceIds.length) {
+ await tx.activityPriceTaxes.deleteMany({
+ where: { activityPriceXid: { in: priceIds } },
+ });
+ await tx.activityPrices.deleteMany({
+ where: { id: { in: priceIds } },
+ });
+ }
+
+ // Clean venues
+ await tx.activityVenues.deleteMany({
+ where: { id: { in: oldVenueIds } },
+ });
+ }
+
+ /* --------------------------------
+ * 8️⃣ CREATE VENUES WITH MEDIA & PRICES
+ * -------------------------------- */
+ for (const venue of payload.venues ?? []) {
+ const venueRow = await tx.activityVenues.create({
+ data: {
+ activityXid,
+ venueName: venue.venueName,
+ venueCapacity: toNumber(venue.venueCapacity) ?? 0,
+ availableSeats: toNumber(venue.availableSeats) ?? 0,
+ isMinPeopleReqMandatory: venue.isMinPeopleReqMandatory,
+ minPeopleRequired: toNumber(venue.minPeopleRequired) ?? null,
+ minReqfullfilledBeforeMins:
+ toNumber(venue.minReqfullfilledBeforeMins) ?? null,
+ venueDescription: venue.venueDescription ?? null,
+ },
+ });
+
+ // Create venue media/artifacts
+ if (Array.isArray(venue.media) && venue.media.length) {
+ await tx.activityVenueArtifacts.createMany({
+ data: venue.media.map((m) => ({
+ activityVenueXid: venueRow.id,
+ mediaType: m.mediaType ?? 'image',
+ mediaFileName: m.mediaFileName,
+ })),
+ });
+ }
+
+ // Create venue prices with taxes
+ for (const price of venue.prices ?? []) {
+ const sellPrice = Number(price.sellPrice);
+ const { basePrice, taxDetails } = computeBasePriceAndTaxes(
+ sellPrice,
+ rootTaxes,
+ );
+
+ const priceRow = await tx.activityPrices.create({
+ data: {
+ activityVenueXid: venueRow.id,
+ noOfSession: price.noOfSession ?? 1,
+ isPackage: price.isPackage ?? false,
+ sessionValidity: price.sessionValidity ?? 0,
+ sessionValidityFrequency: price.sessionValidityFrequency ?? 'Days',
+ basePrice,
+ sellPrice,
+ },
+ });
+
+ if (taxDetails.length) {
+ await tx.activityPriceTaxes.createMany({
+ data: taxDetails.map((t) => ({
+ activityPriceXid: priceRow.id,
+ taxXid: t.taxXid,
+ taxPer: t.taxPer,
+ taxAmount: t.taxAmount,
+ })),
+ });
+ }
+ }
+ }
+
+ /* --------------------------------
+ * 9️⃣ CLEAN & CREATE EQUIPMENT WITH TAXES
+ * -------------------------------- */
+ const oldEquipmentIds = (
+ await tx.activityEquipments.findMany({
+ where: { activityXid },
+ select: { id: true },
+ })
+ ).map((e) => e.id);
+
+ if (oldEquipmentIds.length) {
+ await tx.activityEquipmentTaxes.deleteMany({
+ where: { activityEquipmentXid: { in: oldEquipmentIds } },
+ });
+ await tx.activityEquipments.deleteMany({
+ where: { id: { in: oldEquipmentIds } },
+ });
+ }
+
+ if (Array.isArray(payload.equipments) && payload.equipments.length) {
+ for (const eq of payload.equipments) {
+ const totalPrice = toNumber(eq.equipmentTotalPrice) ?? 0;
+ const { basePrice, taxDetails } = computeBasePriceAndTaxes(
+ totalPrice,
+ rootTaxes,
+ );
+
+ const equipment = await tx.activityEquipments.create({
+ data: {
+ activityXid,
+ equipmentName: eq.equipmentName,
+ isEquipmentChargeable: toBool(eq.isEquipmentChargeable),
+ equipmentBasePrice: basePrice,
+ equipmentTotalPrice: totalPrice,
+ },
+ });
+
+ if (taxDetails.length) {
+ await tx.activityEquipmentTaxes.createMany({
+ data: taxDetails.map((t) => ({
+ activityEquipmentXid: equipment.id,
+ taxXid: t.taxXid,
+ taxPer: t.taxPer,
+ taxAmount: t.taxAmount,
+ })),
+ });
+ }
+ }
+ }
+
+ /* --------------------------------
+ * 🔟 CLEAN & CREATE TRAINER WITH TAXES
+ * -------------------------------- */
+ const oldTrainerIds = (
+ await tx.activityTrainers.findMany({
+ where: { activityXid },
+ select: { id: true },
+ })
+ ).map((t) => t.id);
+
+ if (oldTrainerIds.length) {
+ await tx.activityTrainerTaxes.deleteMany({
+ where: { activityTrainerXid: { in: oldTrainerIds } },
+ });
+ await tx.activityTrainers.deleteMany({
+ where: { id: { in: oldTrainerIds } },
+ });
+ }
+
+ if (payload.trainerAvailable) {
const { basePrice, taxDetails } = computeBasePriceAndTaxes(
- sellPrice,
+ payload.trainerTotalAmount,
rootTaxes,
);
- const priceRow = await tx.activityPrices.create({
+ const trainer = await tx.activityTrainers.create({
data: {
- activityVenueXid: venueRow.id,
- noOfSession: price.noOfSession ?? 1,
- isPackage: price.isPackage ?? false,
- sessionValidity: price.sessionValidity ?? 0,
- sessionValidityFrequency: price.sessionValidityFrequency ?? 'Days',
- basePrice,
- sellPrice,
+ activityXid,
+ baseAmount: basePrice,
+ totalAmount: payload.trainerTotalAmount,
},
});
if (taxDetails.length) {
- await tx.activityPriceTaxes.createMany({
+ await tx.activityTrainerTaxes.createMany({
data: taxDetails.map((t) => ({
- activityPriceXid: priceRow.id,
+ activityTrainerXid: trainer.id,
taxXid: t.taxXid,
taxPer: t.taxPer,
taxAmount: t.taxAmount,
@@ -2314,358 +2645,262 @@ async createOrUpdateActivity(
});
}
}
- }
- /* --------------------------------
- * 9️⃣ CLEAN & CREATE EQUIPMENT WITH TAXES
- * -------------------------------- */
- const oldEquipmentIds = (
- await tx.activityEquipments.findMany({
- where: { activityXid },
- select: { id: true },
- })
- ).map((e) => e.id);
+ /* --------------------------------
+ * 1️⃣1️⃣ CLEAN & CREATE PICKUP/DROP TRANSPORTS WITH DETAILS & TAXES
+ * -------------------------------- */
+ const oldTransportIds = (
+ await tx.activityPickUpTransport.findMany({
+ where: { activityXid },
+ select: { id: true },
+ })
+ ).map((t) => t.id);
- if (oldEquipmentIds.length) {
- await tx.activityEquipmentTaxes.deleteMany({
- where: { activityEquipmentXid: { in: oldEquipmentIds } },
- });
- await tx.activityEquipments.deleteMany({
- where: { id: { in: oldEquipmentIds } },
- });
- }
+ if (oldTransportIds.length) {
+ // Get all pickup details for these transports
+ const oldPickupDetailIds = (
+ await tx.activityPickUpDetails.findMany({
+ where: { activityPickUpTransportXid: { in: oldTransportIds } },
+ select: { id: true },
+ })
+ ).map((p) => p.id);
- if (Array.isArray(payload.equipments) && payload.equipments.length) {
- for (const eq of payload.equipments) {
- const totalPrice = toNumber(eq.equipmentTotalPrice) ?? 0;
+ if (oldPickupDetailIds.length) {
+ // Delete taxes first
+ await tx.activityPickUpTransportTaxes.deleteMany({
+ where: { activityPickUpDetailsXid: { in: oldPickupDetailIds } },
+ });
+ // Delete pickup details
+ await tx.activityPickUpDetails.deleteMany({
+ where: { id: { in: oldPickupDetailIds } },
+ });
+ }
+
+ // Delete transports
+ await tx.activityPickUpTransport.deleteMany({
+ where: { id: { in: oldTransportIds } },
+ });
+ }
+
+ if (
+ Array.isArray(payload.pickupTransports) &&
+ payload.pickupTransports.length
+ ) {
+ for (const transport of payload.pickupTransports) {
+ // Create transport mode
+ const transportRow = await tx.activityPickUpTransport.create({
+ data: {
+ activityXid,
+ transportModeXid: transport.transportModeXid,
+ isTransportModeChargeable: toBool(
+ transport.isTransportModeChargeable,
+ ),
+ },
+ });
+
+ // Create pickup details for this transport
+ if (
+ Array.isArray(transport.pickupDetails) &&
+ transport.pickupDetails.length
+ ) {
+ for (const detail of transport.pickupDetails) {
+ const totalPrice = toNumber(detail.transportTotalPrice) ?? 0;
+ const { basePrice, taxDetails } = computeBasePriceAndTaxes(
+ totalPrice,
+ rootTaxes,
+ );
+
+ const pickupDetail = await tx.activityPickUpDetails.create({
+ data: {
+ activityPickUpTransportXid: transportRow.id,
+ isPickUp: toBool(detail.isPickUp),
+ locationLat: toNumber(detail.locationLat),
+ locationLong: toNumber(detail.locationLong),
+ locationAddress: detail.locationAddress ?? null,
+ transportBasePrice: basePrice,
+ transportTotalPrice: totalPrice,
+ },
+ });
+
+ if (taxDetails.length) {
+ await tx.activityPickUpTransportTaxes.createMany({
+ data: taxDetails.map((t) => ({
+ activityPickUpDetailsXid: pickupDetail.id,
+ taxXid: t.taxXid,
+ taxPer: t.taxPer,
+ taxAmount: t.taxAmount,
+ })),
+ });
+ }
+ }
+ }
+ }
+ }
+
+ /* --------------------------------
+ * 1️⃣2️⃣ CLEAN & CREATE NAVIGATION MODES WITH TAXES
+ * -------------------------------- */
+ const oldNavIds = (
+ await tx.activityNavigationModes.findMany({
+ where: { activityXid },
+ select: { id: true },
+ })
+ ).map((n) => n.id);
+
+ if (oldNavIds.length) {
+ await tx.activityNavigationModesTaxes.deleteMany({
+ where: { activityNavigationModeXid: { in: oldNavIds } },
+ });
+ await tx.activityNavigationModes.deleteMany({
+ where: { id: { in: oldNavIds } },
+ });
+ }
+
+ if (
+ Array.isArray(payload.navigationModes) &&
+ payload.navigationModes.length
+ ) {
+ const totalPrice = toNumber(payload.navigationModeTotalPrice) ?? 0;
const { basePrice, taxDetails } = computeBasePriceAndTaxes(
totalPrice,
rootTaxes,
);
- const equipment = await tx.activityEquipments.create({
- data: {
- activityXid,
- equipmentName: eq.equipmentName,
- isEquipmentChargeable: toBool(eq.isEquipmentChargeable),
- equipmentBasePrice: basePrice,
- equipmentTotalPrice: totalPrice,
- },
- });
-
- if (taxDetails.length) {
- await tx.activityEquipmentTaxes.createMany({
- data: taxDetails.map((t) => ({
- activityEquipmentXid: equipment.id,
- taxXid: t.taxXid,
- taxPer: t.taxPer,
- taxAmount: t.taxAmount,
- })),
+ for (const modeId of payload.navigationModes) {
+ const navMode = await tx.activityNavigationModes.create({
+ data: {
+ activityXid,
+ navigationModeXid: modeId,
+ isInActivityChargeable: toBool(payload.navigationModeIsChargeable),
+ navigationModesBasePrice: basePrice,
+ navigationModesTotalPrice: totalPrice,
+ },
});
- }
- }
- }
- /* --------------------------------
- * 🔟 CLEAN & CREATE TRAINER WITH TAXES
- * -------------------------------- */
- const oldTrainerIds = (
- await tx.activityTrainers.findMany({
- where: { activityXid },
- select: { id: true },
- })
- ).map((t) => t.id);
-
- if (oldTrainerIds.length) {
- await tx.activityTrainerTaxes.deleteMany({
- where: { activityTrainerXid: { in: oldTrainerIds } },
- });
- await tx.activityTrainers.deleteMany({
- where: { id: { in: oldTrainerIds } },
- });
- }
-
- if (payload.trainerAvailable) {
- const { basePrice, taxDetails } = computeBasePriceAndTaxes(
- payload.trainerTotalAmount,
- rootTaxes,
- );
-
- const trainer = await tx.activityTrainers.create({
- data: {
- activityXid,
- baseAmount: basePrice,
- totalAmount: payload.trainerTotalAmount,
- },
- });
-
- if (taxDetails.length) {
- await tx.activityTrainerTaxes.createMany({
- data: taxDetails.map((t) => ({
- activityTrainerXid: trainer.id,
- taxXid: t.taxXid,
- taxPer: t.taxPer,
- taxAmount: t.taxAmount,
- })),
- });
- }
- }
-
- /* --------------------------------
- * 1️⃣1️⃣ CLEAN & CREATE PICKUP/DROP TRANSPORTS WITH DETAILS & TAXES
- * -------------------------------- */
- const oldTransportIds = (
- await tx.activityPickUpTransport.findMany({
- where: { activityXid },
- select: { id: true },
- })
- ).map((t) => t.id);
-
- if (oldTransportIds.length) {
- // Get all pickup details for these transports
- const oldPickupDetailIds = (
- await tx.activityPickUpDetails.findMany({
- where: { activityPickUpTransportXid: { in: oldTransportIds } },
- select: { id: true },
- })
- ).map((p) => p.id);
-
- if (oldPickupDetailIds.length) {
- // Delete taxes first
- await tx.activityPickUpTransportTaxes.deleteMany({
- where: { activityPickUpDetailsXid: { in: oldPickupDetailIds } },
- });
- // Delete pickup details
- await tx.activityPickUpDetails.deleteMany({
- where: { id: { in: oldPickupDetailIds } },
- });
- }
-
- // Delete transports
- await tx.activityPickUpTransport.deleteMany({
- where: { id: { in: oldTransportIds } },
- });
- }
-
- if (
- Array.isArray(payload.pickupTransports) &&
- payload.pickupTransports.length
- ) {
- for (const transport of payload.pickupTransports) {
- // Create transport mode
- const transportRow = await tx.activityPickUpTransport.create({
- data: {
- activityXid,
- transportModeXid: transport.transportModeXid,
- isTransportModeChargeable: toBool(
- transport.isTransportModeChargeable,
- ),
- },
- });
-
- // Create pickup details for this transport
- if (
- Array.isArray(transport.pickupDetails) &&
- transport.pickupDetails.length
- ) {
- for (const detail of transport.pickupDetails) {
- const totalPrice = toNumber(detail.transportTotalPrice) ?? 0;
- const { basePrice, taxDetails } = computeBasePriceAndTaxes(
- totalPrice,
- rootTaxes,
- );
-
- const pickupDetail = await tx.activityPickUpDetails.create({
- data: {
- activityPickUpTransportXid: transportRow.id,
- isPickUp: toBool(detail.isPickUp),
- locationLat: toNumber(detail.locationLat),
- locationLong: toNumber(detail.locationLong),
- locationAddress: detail.locationAddress ?? null,
- transportBasePrice: basePrice,
- transportTotalPrice: totalPrice,
- },
+ if (taxDetails.length) {
+ await tx.activityNavigationModesTaxes.createMany({
+ data: taxDetails.map((t) => ({
+ activityNavigationModeXid: navMode.id,
+ taxXid: t.taxXid,
+ taxPer: t.taxPer,
+ taxAmount: t.taxAmount,
+ })),
});
-
- if (taxDetails.length) {
- await tx.activityPickUpTransportTaxes.createMany({
- data: taxDetails.map((t) => ({
- activityPickUpDetailsXid: pickupDetail.id,
- taxXid: t.taxXid,
- taxPer: t.taxPer,
- taxAmount: t.taxAmount,
- })),
- });
- }
}
}
}
- }
- /* --------------------------------
- * 1️⃣2️⃣ CLEAN & CREATE NAVIGATION MODES WITH TAXES
- * -------------------------------- */
- const oldNavIds = (
- await tx.activityNavigationModes.findMany({
- where: { activityXid },
- select: { id: true },
- })
- ).map((n) => n.id);
+ /* --------------------------------
+ * 1️⃣3️⃣ CLEAN & CREATE AMENITIES
+ * -------------------------------- */
+ await tx.activityAmenities.deleteMany({ where: { activityXid } });
- if (oldNavIds.length) {
- await tx.activityNavigationModesTaxes.deleteMany({
- where: { activityNavigationModeXid: { in: oldNavIds } },
- });
- await tx.activityNavigationModes.deleteMany({
- where: { id: { in: oldNavIds } },
- });
- }
+ if (Array.isArray(payload.amenitiesIds) && payload.amenitiesIds.length) {
+ await tx.activityAmenities.createMany({
+ data: payload.amenitiesIds.map((amenityId) => ({
+ activityXid,
+ amenitiesXid: amenityId,
+ })),
+ });
+ }
- if (
- Array.isArray(payload.navigationModes) &&
- payload.navigationModes.length
- ) {
- const totalPrice = toNumber(payload.navigationModeTotalPrice) ?? 0;
- const { basePrice, taxDetails } = computeBasePriceAndTaxes(
- totalPrice,
- rootTaxes,
- );
+ /* --------------------------------
+ * 1️⃣4️⃣ CLEAN & CREATE ELIGIBILITY
+ * -------------------------------- */
+ await tx.activityEligibility.deleteMany({ where: { activityXid } });
- for (const modeId of payload.navigationModes) {
- const navMode = await tx.activityNavigationModes.create({
+ if (payload.eligibility) {
+ await tx.activityEligibility.create({
data: {
activityXid,
- navigationModeXid: modeId,
- isInActivityChargeable: toBool(payload.navigationModeIsChargeable),
- navigationModesBasePrice: basePrice,
- navigationModesTotalPrice: totalPrice,
+ isAgeRestriction: toBool(payload.eligibility.isAgeRestriction),
+ ageRestrictionXid: toNumber(payload.eligibility.ageRestrictionXid),
+ 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,
+ heightEntered: toNumber(payload.eligibility.heightEntered),
+ heightIn: payload.eligibility.heightIn ?? null,
+ minHeight: toNumber(payload.eligibility.minHeight),
+ maxHeight: toNumber(payload.eligibility.maxHeight),
},
});
-
- if (taxDetails.length) {
- await tx.activityNavigationModesTaxes.createMany({
- data: taxDetails.map((t) => ({
- activityNavigationModeXid: navMode.id,
- taxXid: t.taxXid,
- taxPer: t.taxPer,
- taxAmount: t.taxAmount,
- })),
- });
- }
}
- }
- /* --------------------------------
- * 1️⃣3️⃣ CLEAN & CREATE AMENITIES
- * -------------------------------- */
- await tx.activityAmenities.deleteMany({ where: { activityXid } });
+ /* --------------------------------
+ * 1️⃣5️⃣ CLEAN & CREATE OTHER DETAILS
+ * -------------------------------- */
+ await tx.activityOtherDetails.deleteMany({ where: { activityXid } });
- if (Array.isArray(payload.amenitiesIds) && payload.amenitiesIds.length) {
- await tx.activityAmenities.createMany({
- data: payload.amenitiesIds.map((amenityId) => ({
- activityXid,
- amenitiesXid: amenityId,
- })),
- });
- }
+ if (payload.otherDetails) {
+ await tx.activityOtherDetails.create({
+ data: {
+ activityXid,
+ exclusiveNotes: payload.otherDetails.exclusiveNotes ?? null,
+ dosNotes: payload.otherDetails.dosNotes ?? null,
+ dontsNotes: payload.otherDetails.dontsNotes ?? null,
+ tipsNotes: payload.otherDetails.tipsNotes ?? null,
+ termsAndCondition: payload.otherDetails.termsAndCondition ?? null,
+ },
+ });
+ }
- /* --------------------------------
- * 1️⃣4️⃣ CLEAN & CREATE ELIGIBILITY
- * -------------------------------- */
- await tx.activityEligibility.deleteMany({ where: { activityXid } });
+ /* --------------------------------
+ * 1️⃣6️⃣ CLEAN & CREATE FOOD TYPES
+ * -------------------------------- */
+ await tx.activityFoodTypes.deleteMany({ where: { activityXid } });
- if (payload.eligibility) {
- await tx.activityEligibility.create({
+ if (Array.isArray(payload.foodTypeIds) && payload.foodTypeIds.length) {
+ await tx.activityFoodTypes.createMany({
+ data: payload.foodTypeIds.map((foodTypeId) => ({
+ activityXid,
+ foodTypeXid: foodTypeId,
+ })),
+ });
+ }
+
+ /* --------------------------------
+ * 1️⃣7️⃣ CLEAN & CREATE CUISINES
+ * -------------------------------- */
+ await tx.activityCuisine.deleteMany({ where: { activityXid } });
+
+ if (Array.isArray(payload.cuisineIds) && payload.cuisineIds.length) {
+ await tx.activityCuisine.createMany({
+ data: payload.cuisineIds.map((cuisineId) => ({
+ activityXid,
+ foodCuisineXid: cuisineId,
+ })),
+ });
+ }
+
+ /* --------------------------------
+ * 1️⃣8️⃣ ACTIVITY TRACK
+ * -------------------------------- */
+ await tx.activityTrack.create({
data: {
activityXid,
- isAgeRestriction: toBool(payload.eligibility.isAgeRestriction),
- ageRestrictionXid: toNumber(payload.eligibility.ageRestrictionXid),
- 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,
- heightEntered: toNumber(payload.eligibility.heightEntered),
- heightIn: payload.eligibility.heightIn ?? null,
- minHeight: toNumber(payload.eligibility.minHeight),
- maxHeight: toNumber(payload.eligibility.maxHeight),
+ trackType: 'ACTIVITY',
+ trackStatus: activityInternalStatus,
+ updatedByXid: userId,
+ updatedByRole: ROLE_NAME.HOST,
+ updatedOn: new Date(),
},
});
- }
- /* --------------------------------
- * 1️⃣5️⃣ CLEAN & CREATE OTHER DETAILS
- * -------------------------------- */
- await tx.activityOtherDetails.deleteMany({ where: { activityXid } });
-
- if (payload.otherDetails) {
- await tx.activityOtherDetails.create({
- data: {
- activityXid,
- exclusiveNotes: payload.otherDetails.exclusiveNotes ?? null,
- dosNotes: payload.otherDetails.dosNotes ?? null,
- dontsNotes: payload.otherDetails.dontsNotes ?? null,
- tipsNotes: payload.otherDetails.tipsNotes ?? null,
- termsAndCondition: payload.otherDetails.termsAndCondition ?? null,
- },
- });
- }
-
- /* --------------------------------
- * 1️⃣6️⃣ CLEAN & CREATE FOOD TYPES
- * -------------------------------- */
- await tx.activityFoodTypes.deleteMany({ where: { activityXid } });
-
- if (Array.isArray(payload.foodTypeIds) && payload.foodTypeIds.length) {
- await tx.activityFoodTypes.createMany({
- data: payload.foodTypeIds.map((foodTypeId) => ({
- activityXid,
- foodTypeXid: foodTypeId,
- })),
- });
- }
-
- /* --------------------------------
- * 1️⃣7️⃣ CLEAN & CREATE CUISINES
- * -------------------------------- */
- await tx.activityCuisine.deleteMany({ where: { activityXid } });
-
- if (Array.isArray(payload.cuisineIds) && payload.cuisineIds.length) {
- await tx.activityCuisine.createMany({
- data: payload.cuisineIds.map((cuisineId) => ({
- activityXid,
- foodCuisineXid: cuisineId,
- })),
- });
- }
-
- /* --------------------------------
- * 1️⃣8️⃣ ACTIVITY TRACK
- * -------------------------------- */
- await tx.activityTrack.create({
- data: {
+ /* --------------------------------
+ * 1️⃣9️⃣ RESPONSE
+ * -------------------------------- */
+ return {
activityXid,
- trackType: 'ACTIVITY',
- trackStatus: activityInternalStatus,
- updatedByXid: userId,
- updatedByRole: ROLE_NAME.HOST,
- updatedOn: new Date(),
- },
+ activityRefNumber: activity.activityRefNumber,
+ status: isDraft ? ACTIVITY_INTERNAL_STATUS.ACTIVITY_DRAFT : ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED,
+ };
});
-
- /* --------------------------------
- * 1️⃣9️⃣ RESPONSE
- * -------------------------------- */
- return {
- activityXid,
- activityRefNumber: activity.activityRefNumber,
- status: isDraft ? ACTIVITY_INTERNAL_STATUS.ACTIVITY_DRAFT : ACTIVITY_INTERNAL_STATUS.ACTIVITY_SUBMITTED,
- };
- });
-}
+ }
async getAllPQUpdatedResponse(activityXid: number) {
const pqqHeaderData = await this.prisma.activityPQQheader.findMany({
where: {
diff --git a/src/modules/minglaradmin/handlers/hosthub/hosts/rejectHostApplicationAM.ts b/src/modules/minglaradmin/handlers/hosthub/hosts/rejectHostApplicationAM.ts
index 4e47a59..35ad79d 100644
--- a/src/modules/minglaradmin/handlers/hosthub/hosts/rejectHostApplicationAM.ts
+++ b/src/modules/minglaradmin/handlers/hosthub/hosts/rejectHostApplicationAM.ts
@@ -5,6 +5,7 @@ import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
import ApiError from '../../../../../common/utils/helper/ApiError';
import { MinglarService } from '../../../services/minglar.service';
import { sendAMRejectionMailtoHost } from '../../../services/rejectionMailtoHost.service';
+import config from '../../../../../config/config';
const minglarService = new MinglarService(prismaClient);
@@ -47,7 +48,7 @@ export const handler = safeHandler(async (
// Add suggestion using service
await minglarService.rejectHostApplicationAM(hostXid, userInfo.id);
const hostDetails = await minglarService.getUserDetails(hostXid)
- await sendAMRejectionMailtoHost(hostDetails.emailAddress, hostDetails.firstName)
+ await sendAMRejectionMailtoHost(hostDetails.emailAddress, hostDetails.firstName, config.HOST_LINK)
return {
statusCode: 200,
diff --git a/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts b/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts
index 8f50509..0d2f8f8 100644
--- a/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts
+++ b/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts
@@ -39,7 +39,8 @@ export async function sendEmailToHostForRejectedApplication(
export async function sendAMRejectionMailtoHost(
emailAddress: string,
- name: string
+ name: string,
+ link: string
): Promise<{
sent: boolean;
// messageId: string
@@ -53,8 +54,8 @@ export async function sendAMRejectionMailtoHost(
Please make the necessary improvements and re-submit your application to proceed with the onboarding process on Minglar.
You may access your application using the link below:
Link:
-
- ${config.HOST_LINK}
+
+ ${link}
If you have any questions, please feel free to contact the Minglar Support Team.