diff --git a/serverless/functions/minglaradmin.yml b/serverless/functions/minglaradmin.yml index b945d82..b537cb7 100644 --- a/serverless/functions/minglaradmin.yml +++ b/serverless/functions/minglaradmin.yml @@ -327,6 +327,22 @@ RejectPQQByAM: path: /minglaradmin/hosthub/hosts/reject-pq-by-am method: patch +rejectActivityDetailsApplicationByAM: + handler: src/modules/minglaradmin/handlers/hosthub/hosts/rejectActivityApplicationByAM.handler + memorySize: 384 + package: + patterns: + - 'src/modules/minglaradmin/handlers/hosthub/hosts/rejectActivityApplicationByAM**' + - 'src/modules/minglaradmin/services/**' + - ${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: /minglaradmin/hosthub/hosts/reject-activity-application-by-am + method: patch + acceptPQByAM: handler: src/modules/minglaradmin/handlers/hosthub/hosts/acceptPQByAM.handler memorySize: 384 @@ -343,6 +359,22 @@ acceptPQByAM: path: /minglaradmin/hosthub/hosts/accept-pq-by-am method: patch +acceptActivityDetailsApplicationByAM: + handler: src/modules/minglaradmin/handlers/hosthub/hosts/acceptActivityApplicationByAM.handler + memorySize: 384 + package: + patterns: + - 'src/modules/minglaradmin/handlers/hosthub/hosts/acceptActivityApplicationByAM**' + - 'src/modules/minglaradmin/services/**' + - ${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: /minglaradmin/hosthub/hosts/accept-activity-application-by-am + method: patch + rejectHostApplication: handler: src/modules/minglaradmin/handlers/hosthub/onboarding/rejectHostApplication.handler memorySize: 384 @@ -423,7 +455,6 @@ getAllPQPDetailsForAM: path: /minglaradmin/hosthub/pqp/pqp-details-for-am/{activityXid} method: get - getSuggestionsForAM: handler: src/modules/minglaradmin/handlers/hosthub/onboarding/showSuggestionToAM.handler memorySize: 384 diff --git a/src/common/utils/constants/host.constant.ts b/src/common/utils/constants/host.constant.ts index 4c9f2e2..818d2f2 100644 --- a/src/common/utils/constants/host.constant.ts +++ b/src/common/utils/constants/host.constant.ts @@ -57,7 +57,7 @@ export const ACTIVITY_DISPLAY_STATUS = { ACTIVITY_DRAFT: 'Draft - Activity', ACTIVITY_IN_REVIEW: 'In Review', ACTIVITY_TO_REVIEW: 'To Review', - ACTIVITY_NOT_LISTED: 'Not Listed', + NOT_LISTED: 'Not Listed', ACTIVITY_LISTED: 'Listed', ACTIVITY_UNLISTED: 'Un Listed', }; @@ -95,7 +95,7 @@ export const ACTIVITY_AM_DISPLAY_STATUS = { ACTIVITY_DRAFT: 'Draft - Activity', ACTIVITY_NEW: 'To Review', ACTIVITY_ENHANCING: 'Enhancing', - ACTIVITY_NOT_LISTED: 'Not Listed', + NOT_LISTED: 'Not Listed', ACTIVITY_LISTED: 'Listed', ACITIVITY_REVISED:'Activity Revised' }; diff --git a/src/modules/minglaradmin/handlers/hosthub/hosts/acceptActivityApplicationByAM.ts b/src/modules/minglaradmin/handlers/hosthub/hosts/acceptActivityApplicationByAM.ts new file mode 100644 index 0000000..99e7fd1 --- /dev/null +++ b/src/modules/minglaradmin/handlers/hosthub/hosts/acceptActivityApplicationByAM.ts @@ -0,0 +1,59 @@ +import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; +import { prismaClient } from '../../../../../common/database/prisma.lambda.service'; +import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin'; +import { safeHandler } from '../../../../../common/utils/handlers/safeHandler'; +import ApiError from '../../../../../common/utils/helper/ApiError'; +import { sendActivityAcceptanceMailtoHost } from '../../../../minglaradmin/services/approvalMailtoHost.service'; +import { MinglarService } from '../../../services/minglar.service'; + +const minglarService = new MinglarService(prismaClient); + +interface Body { + activityId: number; +} + +export const handler = safeHandler(async ( + event: APIGatewayProxyEvent, + context?: Context +): Promise => { + 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.'); + + const userInfo = await verifyMinglarAdminToken(token); + + // Parse request body + let body: Body; + + try { + body = event.body ? JSON.parse(event.body) : {}; + } catch (error) { + throw new ApiError(400, 'Invalid JSON in request body'); + } + + const { activityId } = body; + + if (!activityId) { + throw new ApiError(400, 'activityId is required'); + } + + await minglarService.acceptActivityApplicationByAM( + Number(activityId), + Number(userInfo.id) + ); + const hostXid = await minglarService.getHostXidByActivityId(activityId) + const hostDetails = await minglarService.getUserDetails(hostXid) + await sendActivityAcceptanceMailtoHost(hostDetails.emailAddress, hostDetails.firstName) + + return { + statusCode: 201, + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + body: JSON.stringify({ + success: true, + message: 'Approved activity details application successfully', + data: null, + }), + }; +}); diff --git a/src/modules/minglaradmin/handlers/hosthub/hosts/rejectActivityApplicationByAM.ts b/src/modules/minglaradmin/handlers/hosthub/hosts/rejectActivityApplicationByAM.ts new file mode 100644 index 0000000..70ea9cd --- /dev/null +++ b/src/modules/minglaradmin/handlers/hosthub/hosts/rejectActivityApplicationByAM.ts @@ -0,0 +1,59 @@ +import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; +import { prismaClient } from '../../../../../common/database/prisma.lambda.service'; +import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin'; +import { safeHandler } from '../../../../../common/utils/handlers/safeHandler'; +import ApiError from '../../../../../common/utils/helper/ApiError'; +import { sendActivityRejectionMailtoHost } from '../../../../minglaradmin/services/rejectionMailtoHost.service'; +import { MinglarService } from '../../../services/minglar.service'; + +const minglarService = new MinglarService(prismaClient); + +interface Body { + activityId: number; +} + +export const handler = safeHandler(async ( + event: APIGatewayProxyEvent, + context?: Context +): Promise => { + 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.'); + + const userInfo = await verifyMinglarAdminToken(token); + + // Parse request body + let body: Body; + + try { + body = event.body ? JSON.parse(event.body) : {}; + } catch (error) { + throw new ApiError(400, 'Invalid JSON in request body'); + } + + const { activityId } = body; + + if (!activityId) { + throw new ApiError(400, 'activityId is required'); + } + + await minglarService.rejectActivityApplicationByAM( + Number(activityId), + Number(userInfo.id) + ); + const hostXid = await minglarService.getHostXidByActivityId(activityId) + const hostDetails = await minglarService.getUserDetails(hostXid) + await sendActivityRejectionMailtoHost(hostDetails.emailAddress, hostDetails.firstName) + + return { + statusCode: 201, + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + body: JSON.stringify({ + success: true, + message: 'Rejected activity details application successfully', + data: null, + }), + }; +}); diff --git a/src/modules/minglaradmin/services/approvalMailtoHost.service.ts b/src/modules/minglaradmin/services/approvalMailtoHost.service.ts index 06a169a..98c30e5 100644 --- a/src/modules/minglaradmin/services/approvalMailtoHost.service.ts +++ b/src/modules/minglaradmin/services/approvalMailtoHost.service.ts @@ -112,3 +112,41 @@ export async function sendAMPQQAcceptanceMailtoHost( throw new ApiError(500, "Failed to send OTP to minglar admin via email."); } } + +export async function sendActivityAcceptanceMailtoHost( + emailAddress: string, + name: string +): Promise<{ + sent: boolean; + // messageId: string +}> { + + const subject = "Approval for your activity details application"; + + const htmlContent = ` +

Dear ${name},

+

Congratulations, Your activity details application to minglar admin has been approved.

+

You can start getting orders for your activity.

+

You can login to your account using the link below:
+ Link: ${config.HOST_LINK}

+

Best regards,
Minglar Team

+ `; + + 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 minglar admin via email."); + } +} diff --git a/src/modules/minglaradmin/services/minglar.service.ts b/src/modules/minglaradmin/services/minglar.service.ts index 088097a..ca9346d 100644 --- a/src/modules/minglaradmin/services/minglar.service.ts +++ b/src/modules/minglaradmin/services/minglar.service.ts @@ -1820,6 +1820,35 @@ export class MinglarService { }); }); } + + + async rejectActivityApplicationByAM(activityId: number, user_xid: number) { + return await this.prisma.$transaction(async (tx) => { + await tx.activities.update({ + where: { + id: activityId, + isActive: true + }, + data: { + activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_REJECTED, + activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.ENHANCING, + amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_REJECTED, + amDisplayStatus: ACTIVITY_AM_DISPLAY_STATUS.ENHANCING + } + }) + + await tx.activityTrack.create({ + data: { + activityXid: activityId, + trackType: ACTIVITY_TRACK_TYPE.ACTIVITY, + trackStatus: ACTIVITY_TRACK_STATUS.REJECTED_BY_AM, + updatedByXid: user_xid, + updatedByRole: ROLE_NAME.ACCOUNT_MANAGER, + updatedOn: new Date() + } + }) + }) + } async acceptPQByAM(activityId: number, user_xid: number) { return await this.prisma.$transaction(async (tx) => { @@ -1849,6 +1878,35 @@ export class MinglarService { }); } + + async acceptActivityApplicationByAM(activityId: number, user_xid: number) { + return await this.prisma.$transaction(async (tx) => { + await tx.activities.update({ + where: { + id: activityId, + isActive: true + }, + data: { + activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_APPROVED, + activityDisplayStatus: ACTIVITY_DISPLAY_STATUS.NOT_LISTED, + amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_APPROVED, + amDisplayStatus: ACTIVITY_AM_DISPLAY_STATUS.NOT_LISTED + } + }) + + await tx.activityTrack.create({ + data: { + activityXid: activityId, + trackType: ACTIVITY_TRACK_TYPE.ACTIVITY, + trackStatus: ACTIVITY_TRACK_STATUS.ACCEPTED_BY_AM, + updatedByXid: user_xid, + updatedByRole: ROLE_NAME.ACCOUNT_MANAGER, + updatedOn: new Date() + } + }) + }) + } + async getHostDetailsById(host_xid) { const host = await this.prisma.hostHeader.findFirst({ where: { id: host_xid }, diff --git a/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts b/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts index 0d2f8f8..7ee7e89 100644 --- a/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts +++ b/src/modules/minglaradmin/services/rejectionMailtoHost.service.ts @@ -127,3 +127,49 @@ export async function sendAMPQQRejectionMailtoHost( throw new ApiError(500, "Failed to send OTP to minglar admin via email."); } } + + +export async function sendActivityRejectionMailtoHost( + emailAddress: string, + name: string +): Promise<{ + sent: boolean; + // messageId: string +}> { + + const subject = "Improvement of your activity onboarding application"; + + const htmlContent = ` +

Dear ${name},

+ +

Your account manager has reviewed your activity application and provided some suggestions.
+ Please make the necessary improvements and re-submit your activity application along with the pre-qualification answers to proceed with the onboarding process on Minglar.

+ +

You may access your activity onboarding application using the link below:
+ Link: ${config.HOST_LINK}

+ +

If you have any questions, please feel free to contact the Minglar Support Team.

+ +

Best regards,
+ Minglar Team

+ + `; + + 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 minglar admin via email."); + } +}