Untitled
unknown
plain_text
2 years ago
16 kB
9
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