Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as Yup from 'yup';
- import { startOfHour, parseISO, isBefore, format, subHours } from 'date-fns';
- import ptBR from 'date-fns/locale/pt-BR';
- import User from '../models/user';
- import File from '../models/file';
- import Appointment from '../models/appointment';
- import Notification from '../schemas/notification';
- import CancellationMail from '../jobs/cancellationMail';
- import Queue from '../../lib/queue';
- class AppointmentController {
- async index(req, res) {
- const { page = 1 } = req.query;
- const appointments = await Appointment.findAll({
- where: { user_id: req.userId, canceled_at: null },
- order: ['date'],
- attributes: ['id', 'date', 'past', 'cancelable'],
- limit: 20,
- offset: (page - 1) * 20,
- include: [
- {
- model: User,
- as: 'provider',
- attributes: ['id', 'name'],
- include: [
- {
- model: File,
- as: 'avatar',
- attributes: ['id', 'path', 'url'],
- },
- ],
- },
- ],
- });
- return res.json(appointments);
- }
- async store(req, res) {
- const schema = Yup.object().shape({
- provider_id: Yup.number().required(),
- date: Yup.date().required(),
- });
- if (!(await schema.isValid(req.body))) {
- return res.status(400).json({ error: 'Validation fails' });
- }
- const { provider_id, date } = req.body;
- /**
- * Check if provider_id is a provider
- */
- const checkIsProvider = await User.findOne({
- where: { id: provider_id, provider: true },
- });
- if (!checkIsProvider) {
- return res
- .status(401)
- .json({ error: 'You can only create appointments with providers' });
- }
- /**
- * Check for past dates
- */
- const hourStart = startOfHour(parseISO(date));
- if (isBefore(hourStart, new Date())) {
- return res.status(400).json({ erro: 'Past date are not permitted' });
- }
- /**
- * Check date availability
- */
- const checkAvailability = await Appointment.findOne({
- where: {
- provider_id,
- canceled_at: null,
- date: hourStart,
- },
- });
- if (checkAvailability) {
- return res
- .status(401)
- .json({ error: 'Appointment date is not available' });
- }
- const appointment = await Appointment.create({
- user_id: req.userId,
- provider_id,
- date,
- });
- /**
- * Notify appointment provider
- */
- const user = await User.findByPk(req.userId);
- const formattedDate = format(hourStart, "dd 'de' MMMM', às' H:mm'h'", {
- locale: ptBR,
- });
- await Notification.create({
- content: `New appointment to ${user.name} for ${formattedDate}`,
- user: provider_id,
- });
- return res.json(appointment);
- }
- async delete(req, res) {
- // Busca registro a ser deletado
- const appointment = await Appointment.findByPk(req.params.id, {
- include: [
- {
- model: User,
- as: 'provider',
- attributes: ['name', 'email'],
- },
- {
- model: User,
- as: 'user',
- attributes: ['name'],
- },
- ],
- });
- // Verifica se é o próprio usuário que criou o agendamento
- if (appointment.user_id !== req.userId) {
- return res.status(401).json({
- error: "You can't have permition to cancel this appointment.",
- });
- }
- // Calcula limite de cancelamento para 2horas antes do agendamento
- const dateWithSub = subHours(appointment.date, 2);
- // Valida se o horário do agendamento está fora do limite de cancelamento
- if (isBefore(dateWithSub, new Date())) {
- return res.status(401).json({
- error: 'You can only cancel appointments 2 hours in advance.',
- });
- }
- appointment.canceled_at = new Date();
- await appointment.save();
- await Queue.add(CancellationMail.key, {
- appointment,
- });
- return res.json(appointment);
- }
- }
- export default new AppointmentController();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement