140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import authHandler from "@App/middlewares/AuthHandler";
|
|
import roleHandler from "@App/middlewares/RolesHandler";
|
|
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
|
import { Controller, Delete, Post } from "@ControllerPattern/index";
|
|
import { EAppointmentStatus, Votes } from "@prisma/client";
|
|
import LiveVoteService from "@Services/super-admin/LiveVoteService/LiveVoteService";
|
|
import UsersService from "@Services/super-admin/UsersService/UsersService";
|
|
import { validateOrReject } from "class-validator";
|
|
import { Request, Response } from "express";
|
|
import { Vote } from "le-coffre-resources/dist/SuperAdmin";
|
|
import { Service } from "typedi";
|
|
|
|
@Controller()
|
|
@Service()
|
|
export default class LiveVoteController extends ApiController {
|
|
constructor(
|
|
private liveVoteService: LiveVoteService,
|
|
private usersService: UsersService,
|
|
private notificationBuilder: NotificationBuilder,
|
|
) {
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* @description Create a new vote
|
|
*/
|
|
@Post("/api/v1/super-admin/live-votes", [authHandler, roleHandler])
|
|
protected async post(req: Request, response: Response) {
|
|
try {
|
|
const userId = req.body.user.userId;
|
|
//init IUser resource with request body values
|
|
const voteEntity = Vote.hydrate<Vote>(req.body, { strategy: "excludeAll" });
|
|
//validate user
|
|
await validateOrReject(voteEntity, { groups: ["createVote"] });
|
|
|
|
let voteFound = [];
|
|
if (voteEntity.appointment.uid) {
|
|
const appointment = await this.liveVoteService.getAppointmentByUid(voteEntity.appointment.uid);
|
|
if (!appointment) {
|
|
this.httpNotFoundRequest(response, "Appointment not found");
|
|
return;
|
|
}
|
|
if (appointment.status === EAppointmentStatus.CLOSED) {
|
|
this.httpBadRequest(response, "Appointment is closed");
|
|
return;
|
|
}
|
|
voteFound = await this.liveVoteService.getVotes({
|
|
where: { AND: [{ appointment: { uid: voteEntity.appointment.uid } }, { voter: { uid: userId } }] },
|
|
});
|
|
} else {
|
|
voteFound = await this.liveVoteService.getVotes({
|
|
where: {
|
|
AND: [
|
|
{
|
|
appointment: {
|
|
AND: [{ user_uid: voteEntity.appointment.user.uid }, { status: EAppointmentStatus.OPEN }],
|
|
},
|
|
},
|
|
{ voter: { uid: userId } },
|
|
],
|
|
},
|
|
});
|
|
}
|
|
|
|
if (voteFound.length) {
|
|
this.httpBadRequest(response, "Voter already voted for this appointment");
|
|
return;
|
|
}
|
|
|
|
const voter = await this.usersService.getByUid(userId);
|
|
|
|
voteEntity.voter = voter!;
|
|
//call service to get prisma entity
|
|
const voteEntityCreated = await this.liveVoteService.create(voteEntity);
|
|
|
|
if (!voteEntityCreated) {
|
|
this.httpBadRequest(response, "Appointment choice is not valid");
|
|
return;
|
|
}
|
|
//Hydrate ressource with prisma entity
|
|
const vote = Vote.hydrate<Vote>(voteEntityCreated, { strategy: "excludeAll" });
|
|
|
|
await this.notificationBuilder.sendVoteNotification(vote);
|
|
|
|
//success
|
|
this.httpCreated(response, vote);
|
|
} catch (error) {
|
|
this.httpInternalError(response, error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @description Delete a specific vote
|
|
*/
|
|
@Delete("/api/v1/super-admin/live-votes/:uid", [authHandler, roleHandler])
|
|
protected async deleteVote(req: Request, response: Response) {
|
|
try {
|
|
const uid = req.params["uid"];
|
|
if (!uid) {
|
|
this.httpBadRequest(response, "No uid provided");
|
|
return;
|
|
}
|
|
|
|
const voteFound = await this.liveVoteService.getVoteByUid(uid, {
|
|
appointment: {
|
|
include: { votes: true },
|
|
},
|
|
});
|
|
|
|
if (!voteFound) {
|
|
this.httpNotFoundRequest(response, "vote not found");
|
|
return;
|
|
}
|
|
|
|
if (voteFound.voter_uid !== req.body.user.userId) {
|
|
this.httpUnauthorized(response, "Can't delete a vote that's not yours");
|
|
return;
|
|
}
|
|
|
|
const vote = Vote.hydrate<Vote>(voteFound, { strategy: "excludeAll" });
|
|
|
|
//call service to get prisma entity
|
|
const voteEntity: Votes = await this.liveVoteService.deleteVote(uid);
|
|
|
|
if (vote.appointment.uid && vote.appointment.votes && vote.appointment.votes.length === 1) {
|
|
await this.liveVoteService.deleteAppointment(vote.appointment.uid);
|
|
}
|
|
|
|
const voteToReturn = Vote.hydrate<Vote>(voteEntity, { strategy: "excludeAll" });
|
|
//success
|
|
this.httpSuccess(response, voteToReturn);
|
|
} catch (error) {
|
|
this.httpInternalError(response, error);
|
|
return;
|
|
}
|
|
}
|
|
}
|