import { Controller, Post, Body, UseGuards } from '@nestjs/common' import { isEmpty } from 'lodash' import { zonedTimeToUtc } from 'date-fns-tz' import { endOfDay, startOfDay } from 'date-fns' import { APPOINTMENT_TYPES, Booking, GeneralAppointmentsReport, GENERAL_REPORT_ARGS } from '../domain' import { BasicAuthorizationGuard } from '../../../guards' import { parseISO } from '../../../utils/date' import { Roles } from '../../../models' import { UnauthorizedError } from '../../../errors' import { CountryHelper } from '../../../utils/countries' import { AppointmentsReportInput, AppointmentsReportParams } from './params' @UseGuards(BasicAuthorizationGuard) @Controller('nutritionists/report') export class ReportController { constructor(private readonly booking: Booking) {} @Post('appointments') async appointments( @Body() { input, session_variables }: AppointmentsReportParams, ): Promise { this.validateAuthUser( session_variables['x-hasura-role'], session_variables['x-hasura-user-id'], input.nutritionist_id, ) const generalArgs = this.getReportArgs(input) if (!isEmpty(input.nutritionist_id)) return this.booking.generateNutritionistData({ ...generalArgs, nutritionistId: input.nutritionist_id, }) if (input.appointment_type) return await this.booking.generateGeneralData({ ...generalArgs }) return await APPOINTMENT_TYPES.reduce( async (previous, current) => ({ ...(await previous), ...(await this.booking.generateGeneralData({ ...generalArgs, appointmentType: current })), }), Promise.resolve({}), ) } private validateAuthUser(role: string, authId: string, userId: string): void { if (role !== Roles.NUTRITIONIST_MANAGER && role !== Roles.ADMIN && userId !== authId) throw new UnauthorizedError(authId, 'Permitido acesso somente para o próprio usuário.') } private getReportArgs(input: AppointmentsReportInput): GENERAL_REPORT_ARGS { const timezone = CountryHelper.getTimezoneByCountry(input.country_code) const beginDate = zonedTimeToUtc(startOfDay(parseISO(input.begin_date)), timezone) const endDate = zonedTimeToUtc(endOfDay(parseISO(input.end_date)), timezone) const generalArgs: GENERAL_REPORT_ARGS = { beginDate, endDate, countryCode: input.country_code, appointmentType: input.appointment_type, } return generalArgs } }