require 'restclient' module Medivo class Appointment LABCORP_FORMAT = "%m/%d/%Y|%H:%M %p" unless defined? LABCORP_FORMAT MDY_FORMAT = "%m/%d/%Y" unless defined? MDY_FORMAT class << self ## # Find a labcorp appointment # # @param lab_code lab code # @param date date to seek # @param am_pm optional time of day value ( 'AM' or 'PM' ) # # @return Hash { :times=>['time1', 'time2'] } # # @throws exception mainly Restclient::Exception types def find(lab_code, date, am_pm='') if real_data? data = resource.get :params=>{:labcorp_id=>lab_code, :appointment_date=>date} # data is json encoded hash: { :times => ['time1', 'time2'] } data = JSON.parse(data)['times'] else data = build_fake_data(date) end # filter the hash before returning {'times'=> filter_data(data, am_pm)} end ## # Make the labcorp appointment # # @param lab_code lab code # @param time time # @param user user info must include date_of_birth, first_name, last_name, # email_address, phone_number # # @return String confirmation number or nil if none made # # @throws exception mainly Restclient::Exception types def make(lab_code, time, user) time_id = time.strftime(LABCORP_FORMAT) if real_data? data = resource.post :labcorp_id=>lab_code, :time_id=>time_id, :user=>user # data is json { :confimation => ( 'real number' or nil if no appointment made ) } JSON.parse(data)['confirmation'] else nil end end def resource @resource ||= begin @config = ResourceConfig.find 'appointment_resource.yml' RestClient::Resource.new @config.href, :timeout => (@config.timeout || 12) rescue => e Rails.logger.error e.inspect # blow up later, so the server can start end end ## using real data? # the flag is set in the config/appointment_resource.yml def real_data? resource # to init the resource and config file true unless !Rails.env.test? and @config.real_data == false end def filter_data(times, am_pm) now = Time.now times.collect! { |time| OpenStruct.new(time: (Time.strptime(time, LABCORP_FORMAT) rescue nil), time_str: time) } times.reject! { |o| !o.time or !o.time_str.match(/#{am_pm}/) or (o.time < now) } times.sort_by! {|o| o.time } times.collect! { |o| o.time_str } end def build_fake_data(date) date = date.is_a?(String) ? Date.strptime(date, MDY_FORMAT) : date [ build_date(date, "08:30 AM"), build_date(date, "10:30 AM"), build_date((date + 1), "03:30 PM"), build_date((date+1), "01:30 PM"), build_date((date + 2), "10:30 AM"), build_date((date+1), "03:00 PM"), ] end def build_date(date, time) "#{date.strftime(MDY_FORMAT)}|#{time}" end end end end