Untitled
unknown
plain_text
a year ago
16 kB
2
Indexable
/* eslint-disable prettier/prettier */ /* eslint-disable @typescript-eslint/no-var-requires */ import { PrismaService } from '@libs/modules/prisma/prisma.service'; import { ForbiddenException, HttpException, Injectable, NotFoundException, } from '@nestjs/common'; import { PaginateInput } from '@common/paginate/dto/paginate.input'; import { createPaginator } from 'prisma-pagination'; import { ModelOnCampaign, Prisma } from '@prisma/client'; import { handlePaginateInput } from '@common/paginate/utils'; import { FilterRegisterCampaignInput } from './dto/filter-register-campaign.input'; import { filterByContainFunc } from '@common/query'; import { CampaignStatus, RegisterStatus, RegisterStatusFilter, ScheduleType } from '@common/guard/enum'; import { KycStatus } from '@modules/model/config'; import { TelegramService } from '@libs/modules/telegram/telegram.service'; import { FirebaseService } from '@libs/modules/firebase/firebase.service'; import { TypeNotification } from '@libs/modules/firebase/model/dataNotification'; const dayjs = require('dayjs'); const utc = require('dayjs/plugin/utc'); dayjs.extend(utc); @Injectable() export class RegisterCampaignService { constructor(private prisma: PrismaService, private telegramService: TelegramService, private firebaseService: FirebaseService) { } async register(modelId: number, campaignRoleId: number) { try { const check = await this.checkRegistedAndDate(modelId, campaignRoleId); if (check.value) { throw new ForbiddenException('Bạn đã đăng ký'); } const result = await this.prisma.modelOnCampaign.create({ data: { modelId, campaignRoleId, status: RegisterStatus.REGISTERED }, }); const message = '💥💥💥 `Yêu cầu ứng tuyển` 💥💥💥\n' + `👤 *Tên mẫu*: ${check.data.model.user.firstname} ${check.data.model.user.lastname}\n` + `✉️ *Email*: ${check.data.model.user.email}\n` + `🗞 *Chiến dịch*: ${check.data.campaignRole.campaign.name}\n` + `🧑 *Vai trò*: ${check.data.campaignRole.name}\n` + `📍 *Xem ngay tại*: https://felix-admin.zackco.com/data/campaign/detail?id=${check.data.campaignRole.campaignId}`; this.telegramService.sendMessage(message) return result; } catch (error) { console.log("register campaign") console.log(error) throw new ForbiddenException(error.message); } } async checkRegistedAndDate(modelId: number, campaignRoleId: number) { try { const campaignRole = await this.prisma.campaignRole.findUnique({ where: { id: campaignRoleId }, include: { campaign: true, } }) if (!campaignRole) { throw new ForbiddenException("Campaign role không tồn tại") } if (campaignRole.campaign.status !== CampaignStatus.PROCESSING) { throw new ForbiddenException('Casting không hợp lệ'); } const available = await this.prisma.modelOnCampaign.findMany({ where: { campaignRoleId, status: RegisterStatus.ACCEPTED, }, take: Number(campaignRole.quantity) }); if (available.length >= Number(campaignRole.quantity)) { throw new ForbiddenException("Vai trò này đã tuyển đủ số lượng mẫu") } const check = await this.prisma.modelOnCampaign.findUnique({ where: { campaignRoleId_modelId: { campaignRoleId, modelId }, }, include: { campaignRole: { include: { campaign: true } }, model: { include: { user: true, } }, }, }); if (check) { return { data: check, value: true }; } const model = await this.prisma.model.findUnique({ where: { id: modelId, }, include: { user: true } }) if (model.kycStatus !== KycStatus.VERIFIED) { throw new ForbiddenException("Bạn chưa xác minh thông tin cá nhân") } const schedule = await this.findScheduleInRange( modelId, campaignRole.campaign.startFittingDate, campaignRole.campaign.endFittingDate, campaignRole.startShootingDate, campaignRole.endShootingDate, ) if (schedule) { throw new ForbiddenException("Bạn đã có lịch bận/làm việc trùng với ngày thử đồ hoặc ngày quay") } return { data: { campaignRole, model }, value: false }; } catch (error) { console.log(error); throw new ForbiddenException(error.message); } } async findAll( paginateInput: PaginateInput, filter?: FilterRegisterCampaignInput, ) { const paginateInputHandle = handlePaginateInput(paginateInput); const paginate = createPaginator({ ...paginateInputHandle }); const { startFittingDate, endFittingDate, startShootingDate, endShootingDate, name: n, status, campaignId, ...fil } = filter; const name = filterByContainFunc(filter?.name); const now = dayjs().add(7, 'hour').toISOString(); // Set the timezone offset as needed const result = await paginate< ModelOnCampaign, Prisma.ModelOnCampaignFindManyArgs >(this.prisma.modelOnCampaign, { where: { AND: [ { ...fil, status: status && status !== RegisterStatusFilter.UPCOMING ? status : {} }, { campaignRole: { AND: [ { campaign: { AND: [ { id: campaignId }, { name }, status && status === RegisterStatusFilter.UPCOMING ? { startFittingDate: { gte: now } } : {}, { startFittingDate: { gte: startFittingDate } }, { endFittingDate: { lte: endFittingDate } }, ], } }, { startShootingDate: { gte: startShootingDate } }, { endShootingDate: { lte: endShootingDate } }, ] }, }, ], }, include: { campaignRole: { include: { campaign: true } }, model: { include: { user: true } } }, }); return result; } async findOne(modelId: number, campaignRoleId: number) { try { const data = await this.prisma.modelOnCampaign.findUnique({ where: { campaignRoleId_modelId: { campaignRoleId, modelId }, }, include: { campaignRole: { include: { campaign: true } }, model: { include: { user: true } }, }, }); if (!data) { throw new NotFoundException('Không tìm thấy'); } return data; } catch (error) { if (error instanceof NotFoundException) { throw error; } else { throw new ForbiddenException('Có lỗi xảy ra'); } } } async createScheduleWhenAccept(modelId: number, campaignRoleId: number, name: string, startFittingDate: Date, endFittingDate: Date, startShootingDate: Date, endShootingDate: Date) { try { return await this.prisma.schedule.createMany({ data: [ { modelId, campaignRoleId, startDate: startFittingDate, endDate: endFittingDate, type: ScheduleType.WORK, detail: `Lịch thử đồ cho casting ${name}` }, { modelId, campaignRoleId, startDate: startShootingDate, endDate: endShootingDate, type: ScheduleType.WORK, detail: `Lịch quay cho casting ${name}` }, ] }) } catch (error) { console.log(error) } } async removeScheduleWhenReject(campaignRoleId: number) { return this.prisma.schedule.deleteMany({ where: { campaignRoleId } }) } findScheduleInRange(modelId: number, startFittingDate: Date, endFittingDate: Date, startShootingDate: Date, endShootingDate: Date) { return this.prisma.schedule.findFirst({ where: { modelId, type: { in: [ScheduleType.BUSY, ScheduleType.WORK] }, OR: [ { startDate: { gte: startFittingDate, lte: endFittingDate, }, }, { endDate: { gte: startFittingDate, lte: endFittingDate, }, }, { startDate: { lte: startFittingDate, }, endDate: { gte: startFittingDate, }, }, { startDate: { lte: endFittingDate, }, endDate: { gte: endFittingDate, }, }, // Shooting { startDate: { gte: startShootingDate, lte: endShootingDate, }, }, { endDate: { gte: startShootingDate, lte: endShootingDate, }, }, { startDate: { lte: startShootingDate, }, endDate: { gte: startShootingDate, }, }, { startDate: { lte: endShootingDate, }, endDate: { gte: endShootingDate, }, }, ], } }) } async update(modelId: number, campaignRoleId: number, status: RegisterStatus, role) { const data = await this.findOne(modelId, campaignRoleId); if (role === 'ADMIN') { if (status && data.status === RegisterStatus.REJECTED && (status !== RegisterStatus.ACCEPTED && status !== RegisterStatus.REJECTED && status !== RegisterStatus.REGISTERED)) { throw new ForbiddenException('Chuyển trạng thái không hợp lệ'); } if (status && data.status === RegisterStatus.COMPLETED) { throw new ForbiddenException('Không thể cập nhật trạng thái khi đã từ chối hoặc hoàn thành'); } if (status && status === RegisterStatus.COMPLETED && data.status === RegisterStatus.REGISTERED) { throw new ForbiddenException('Không thể cập nhật trạng thái từ đăng ký sang hoàn thành'); } if (status && status === RegisterStatus.COMPLETED && data.status === RegisterStatus.REJECTED) { throw new ForbiddenException('Không thể cập nhật trạng thái từ hủy sang hoàn thành'); } if (status && status === RegisterStatus.ACCEPTED) { const schedule = await this.findScheduleInRange( modelId, data.campaignRole.campaign.startFittingDate, data.campaignRole.campaign.endFittingDate, data.campaignRole.startShootingDate, data.campaignRole.endShootingDate, ) if (schedule) { throw new ForbiddenException("Mẫu đã có lịch bận/du lịch trùng với ngày thử đồ hoặc ngày quay") } else { this.createScheduleWhenAccept(modelId, campaignRoleId, data.campaignRole.name, data.campaignRole.campaign.startFittingDate, data.campaignRole.campaign.endFittingDate, data.campaignRole.startShootingDate, data.campaignRole.endShootingDate) const message = '💥💥💥 `Ứng tuyển chờ duyệt thành công` 💥💥💥\n' + `👤 *Tên mẫu*: ${data.model.user.firstname} ${data.model.user.lastname}\n` + `✉️ *Email*: ${data.model.user.email}\n` + `🗞 *Chiến dịch*: ${data.campaignRole.campaign.name}\n` + `🧑 *Vai trò*: ${data.campaignRole.name}\n` + `📍 *Xem ngay tại*: https://felix-admin.zackco.com/data/campaign/detail?id=${data.campaignRole.campaignId}`; this.telegramService.sendMessage(message) } } if (status && status === RegisterStatus.REJECTED) { this.removeScheduleWhenReject(campaignRoleId) const message = '💥💥💥 `Ứng tuyển bị từ chối` 💥💥💥\n' + `👤 *Tên mẫu*: ${data.model.user.firstname} ${data.model.user.lastname}\n` + `✉️ *Email*: ${data.model.user.email}\n` + `🗞 *Chiến dịch*: ${data.campaignRole.campaign.name}\n` + `🧑 *Vai trò*: ${data.campaignRole.name}\n` + `📍 *Xem ngay tại*: https://felix-admin.zackco.com/data/campaign/detail?id=${data.campaignRole.campaignId}`; this.telegramService.sendMessage(message) } const now = dayjs().add(7, 'hour'); if (status && status === RegisterStatus.COMPLETED && dayjs(data.campaignRole.endShootingDate).isAfter(now)) { throw new ForbiddenException("Không thể cập nhật sang trạng thái hoàn thành vì ngày quay của phân vai này chưa qua") } } else { if ( status && status === RegisterStatus.CANCELED && data.status !== RegisterStatus.REGISTERED ) { throw new ForbiddenException('Không thể cập nhật trạng thái'); } if ( status && status === RegisterStatus.CANCELED && data.status === RegisterStatus.REGISTERED ) { try { await this.prisma.modelOnCampaign.delete({ where: { campaignRoleId_modelId: { campaignRoleId, modelId } }, }); return "Hủy thành công" } catch (error) { throw new ForbiddenException(error.message); } } } try { const result = await this.prisma.modelOnCampaign.update({ where: { campaignRoleId_modelId: { campaignRoleId, modelId } }, data: { status }, }); if (status === RegisterStatus.ACCEPTED || status === RegisterStatus.REJECTED) { const mes = status === RegisterStatus.ACCEPTED ? msg: `Chúc mừng bạn đã được chọn cho job "..." với vai "..."."` : `Rất tiếc bạn chưa phù hợp cho job "...". Hãy tiếp tục theo dõi Felix Zone để cập nhật những job mới phù hợp sắp tới nhé` this.firebaseService.sendNotificationToUser(data.modelId, `Ứng tuyển ${mes.stt}`, `Yêu cầu ứng tuyển vào sự kiện ${data.campaignRole.campaign.name} với vai trò ${data.campaignRole.name} ${mes.stt}`, { type: TypeNotification.processing_campaign, data: { message: 'Có sự kiện mới. Truy cập vào ứng dụng ngay để xem chi tiết' } as any }) } return result; } catch (error) { throw new ForbiddenException(error.message); } } async remove(modelId: number, campaignRoleId: number) { await this.findOne(modelId, campaignRoleId); try { await this.prisma.modelOnCampaign.delete({ where: { campaignRoleId_modelId: { campaignRoleId, modelId } }, }); return 'Xóa thành công' } catch (error) { throw new ForbiddenException(error.message); } } }
Editor is loading...
Leave a Comment