Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import * as Yup from 'yup';
  2. import { startOfHour, parseISO, isBefore, format, subHours } from 'date-fns';
  3. import ptBR from 'date-fns/locale/pt-BR';
  4. import User from '../models/user';
  5. import File from '../models/file';
  6. import Appointment from '../models/appointment';
  7. import Notification from '../schemas/notification';
  8. import CancellationMail from '../jobs/cancellationMail';
  9. import Queue from '../../lib/queue';
  10.  
  11. class AppointmentController {
  12.   async index(req, res) {
  13.     const { page = 1 } = req.query;
  14.  
  15.     const appointments = await Appointment.findAll({
  16.       where: { user_id: req.userId, canceled_at: null },
  17.       order: ['date'],
  18.       attributes: ['id', 'date', 'past', 'cancelable'],
  19.       limit: 20,
  20.       offset: (page - 1) * 20,
  21.       include: [
  22.         {
  23.           model: User,
  24.           as: 'provider',
  25.           attributes: ['id', 'name'],
  26.           include: [
  27.             {
  28.               model: File,
  29.               as: 'avatar',
  30.               attributes: ['id', 'path', 'url'],
  31.             },
  32.           ],
  33.         },
  34.       ],
  35.     });
  36.  
  37.     return res.json(appointments);
  38.   }
  39.  
  40.   async store(req, res) {
  41.     const schema = Yup.object().shape({
  42.       provider_id: Yup.number().required(),
  43.       date: Yup.date().required(),
  44.     });
  45.  
  46.     if (!(await schema.isValid(req.body))) {
  47.       return res.status(400).json({ error: 'Validation fails' });
  48.     }
  49.  
  50.     const { provider_id, date } = req.body;
  51.  
  52.     /**
  53.      * Check if provider_id is a provider
  54.      */
  55.     const checkIsProvider = await User.findOne({
  56.       where: { id: provider_id, provider: true },
  57.     });
  58.  
  59.     if (!checkIsProvider) {
  60.       return res
  61.         .status(401)
  62.         .json({ error: 'You can only create appointments with providers' });
  63.     }
  64.  
  65.     /**
  66.      * Check for past dates
  67.      */
  68.     const hourStart = startOfHour(parseISO(date));
  69.  
  70.     if (isBefore(hourStart, new Date())) {
  71.       return res.status(400).json({ erro: 'Past date are not permitted' });
  72.     }
  73.  
  74.     /**
  75.      * Check date availability
  76.      */
  77.     const checkAvailability = await Appointment.findOne({
  78.       where: {
  79.         provider_id,
  80.         canceled_at: null,
  81.         date: hourStart,
  82.       },
  83.     });
  84.  
  85.     if (checkAvailability) {
  86.       return res
  87.         .status(401)
  88.         .json({ error: 'Appointment date is not available' });
  89.     }
  90.  
  91.     const appointment = await Appointment.create({
  92.       user_id: req.userId,
  93.       provider_id,
  94.       date,
  95.     });
  96.  
  97.     /**
  98.      * Notify appointment provider
  99.      */
  100.     const user = await User.findByPk(req.userId);
  101.     const formattedDate = format(hourStart, "dd 'de' MMMM', às' H:mm'h'", {
  102.       locale: ptBR,
  103.     });
  104.  
  105.     await Notification.create({
  106.       content: `New appointment to ${user.name} for ${formattedDate}`,
  107.       user: provider_id,
  108.     });
  109.  
  110.     return res.json(appointment);
  111.   }
  112.  
  113.   async delete(req, res) {
  114.     // Busca registro a ser deletado
  115.     const appointment = await Appointment.findByPk(req.params.id, {
  116.       include: [
  117.         {
  118.           model: User,
  119.           as: 'provider',
  120.           attributes: ['name', 'email'],
  121.         },
  122.         {
  123.           model: User,
  124.           as: 'user',
  125.           attributes: ['name'],
  126.         },
  127.       ],
  128.     });
  129.  
  130.     // Verifica se é o próprio usuário que criou o agendamento
  131.     if (appointment.user_id !== req.userId) {
  132.       return res.status(401).json({
  133.         error: "You can't have permition to cancel this appointment.",
  134.       });
  135.     }
  136.  
  137.     // Calcula limite de cancelamento para 2horas antes do agendamento
  138.     const dateWithSub = subHours(appointment.date, 2);
  139.  
  140.     // Valida se o horário do agendamento está fora do limite de cancelamento
  141.     if (isBefore(dateWithSub, new Date())) {
  142.       return res.status(401).json({
  143.         error: 'You can only cancel appointments 2 hours in advance.',
  144.       });
  145.     }
  146.  
  147.     appointment.canceled_at = new Date();
  148.     await appointment.save();
  149.  
  150.     await Queue.add(CancellationMail.key, {
  151.       appointment,
  152.     });
  153.  
  154.     return res.json(appointment);
  155.   }
  156. }
  157.  
  158. export default new AppointmentController();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement