'use server' import logRequestResult from '@/lib/services/audit.service'; import { RequestStatus } from '@/lib/types/audit'; import { AvailableAppointmentsResponse, BookTimeResponse, ConfirmedLoadResponse, ConnectedOnlineMethodName, } from '@/lib/types/connected-online'; import { ExternalApi } from '@/lib/types/external'; import { Tables } from '@/supabase/database.types'; import { createClient } from '@/utils/supabase/server'; import axios from 'axios'; export async function getAvailableAppointmentsForService( serviceId: number, startTime?: Date, ) { try { const showTimesFrom = startTime ? { StartTime: startTime } : {}; const response = await axios.post( `${process.env.CONNECTED_ONLINE_URL!}/${ConnectedOnlineMethodName.GetAvailabilities}`, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, param: JSON.stringify({ ServiceID: serviceId, Key: '7T624nlu', Lang: 'et', ...showTimesFrom, }), }, ); const responseData: AvailableAppointmentsResponse = JSON.parse( response.data.d, ); if ( responseData?.ErrorCode !== 0 || !responseData.Data.T_Service?.length || !responseData.Data.T_Booking?.length ) { let comment = `Response returned error code ${responseData.ErrorCode}, message: ${responseData.ErrorMessage}`; if (responseData?.ErrorCode === 0) { comment = responseData.Data.T_Service?.length ? `No service present in appointment availability response, service id: ${serviceId}, start time: ${startTime}` : `No booking times present in appointment availability response, service id: ${serviceId}, start time: ${startTime}`; } await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.GetAvailabilities, RequestStatus.Fail, comment, ); return null; } await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.GetAvailabilities, RequestStatus.Success, JSON.stringify(responseData), ); return responseData.Data; } catch (error) { await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.GetAvailabilities, RequestStatus.Fail, JSON.stringify(error), ); return null; } } export async function bookAppointment( serviceSyncId: number, clinicId: number, appointmentUserId: number, syncUserID: number, startTime: string, locationId = 0, comments = '', isEarlierTimeRequested = false, earlierTimeRequestComment = '', ) { const supabase = await createClient(); try { const { data: { user }, } = await supabase.auth.getUser(); if (!user?.id) { throw new Error('User not authenticated'); } const [ { data: dbClinic, error: clinicError }, { data: dbService, error: serviceError }, ] = await Promise.all([ supabase .from('connected_online_providers') .select('*') .eq('id', clinicId) .limit(1), supabase .from('connected_online_services') .select('*') .eq('sync_id', serviceSyncId) .eq('clinic_id', clinicId) .limit(1), ]); if (!dbClinic?.length || !dbService?.length) { return logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.BookTime, RequestStatus.Fail, dbClinic?.length ? `Could not find clinic with id ${clinicId}, error: ${JSON.stringify(clinicError)}` : `Could not find service with sync id ${serviceSyncId} and clinic id ${clinicId}, error: ${JSON.stringify(serviceError)}`, startTime, serviceSyncId, clinicId, ); } const clinic: Tables<'connected_online_providers'> = dbClinic![0]; const service: Tables<'connected_online_services'> = dbService![0]; // TODO the dummy data needs to be replaced with real values once they're present on the user/account const response = await axios.post( `${process.env.CONNECTED_ONLINE_URL!}/${ConnectedOnlineMethodName.BookTime}`, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, param: JSON.stringify({ EarlierTime: isEarlierTimeRequested, // once we have the e-shop functionality we can let the user select if she would like to be offered earlier time slots if they become available EarlierTimeComment: earlierTimeRequestComment, ClinicID: clinic.id, ServiceID: service.id, ClinicServiceID: service.sync_id, UserID: appointmentUserId, SyncUserID: syncUserID, StartTime: startTime, FirstName: 'Test', LastName: 'User', PersonalCode: '4', Email: user.email, Phone: 'phone', Comments: comments, Location: locationId, FreeCode: '', AddToBasket: false, Key: '7T624nlu', Lang: 'et', // update when integrated into app, if needed }), }, ); const responseData: BookTimeResponse = JSON.parse(response.data.d); if (responseData?.ErrorCode !== 0 || !responseData.Value) { return logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.BookTime, RequestStatus.Fail, JSON.stringify(responseData), startTime, service.id, clinicId, ); } const responseParts = responseData.Value.split(','); const { error } = await supabase .from('connected_online_reservation') .insert({ booking_code: responseParts[1], clinic_id: clinic.id, comments, lang: 'et', // change later, if needed service_id: service.id, service_user_id: appointmentUserId, start_time: startTime, sync_user_id: syncUserID, requires_payment: !!responseParts[0], user_id: user.id, }); await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.BookTime, RequestStatus.Success, JSON.stringify(responseData), startTime, service.id, clinicId, ); if (error) { throw new Error(error.message); } return responseData.Value; } catch (error) { return logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.BookTime, RequestStatus.Fail, JSON.stringify(error), startTime, serviceSyncId, clinicId, ); } } export async function getConfirmedService(reservationCode: string) { try { const response = await axios.post( `${process.env.CONNECTED_ONLINE_URL!}/${ConnectedOnlineMethodName.ConfirmedLoad}`, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, param: JSON.stringify({ Value: `${reservationCode}|7T624nlu|et` }), }, ); const responseData: ConfirmedLoadResponse = JSON.parse(response.data.d); if (responseData?.ErrorCode !== 0) { await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.ConfirmedLoad, RequestStatus.Fail, JSON.stringify(responseData), ); return null; } await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.ConfirmedLoad, RequestStatus.Success, JSON.stringify(responseData), ); return responseData.Data; } catch (error) { await logRequestResult( ExternalApi.ConnectedOnline, ConnectedOnlineMethodName.ConfirmedLoad, RequestStatus.Fail, JSON.stringify(error), ); return null; } }