Class: TocDoc::Availability::Collection
- Inherits:
-
Object
- Object
- TocDoc::Availability::Collection
- Includes:
- Enumerable
- Defined in:
- lib/toc_doc/models/availability/collection.rb
Overview
An Enumerable collection of TocDoc::Availability instances returned by where.
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#query ⇒ Object
readonly
Returns the value of attribute query.
Instance Method Summary collapse
-
#availabilities ⇒ Array<TocDoc::Availability>
(also: #all)
All TocDoc::Availability instances that have at least one slot.
-
#booking_url ⇒ String?
Builds a Doctolib booking URL for the current query context.
-
#each {|availability| ... } ⇒ Enumerator
Iterates over TocDoc::Availability instances that have at least one slot.
-
#initialize(data, query: {}, path: '/availabilities.json', client: nil) ⇒ Collection
constructor
A new instance of Collection.
-
#load_next! ⇒ self
Fetches the next window of availabilities and merges it into this collection.
-
#merge_page!(page_data) ⇒ self
Fetches the next window of availabilities (starting the day after the last date in the current collection) and merges them in.
-
#more? ⇒ Boolean
Returns +true+ when the API has indicated that more results exist beyond the currently loaded pages.
-
#next_slot ⇒ String?
The nearest available appointment slot.
-
#raw_availabilities ⇒ Array<TocDoc::Availability>
All date entries — including those with no slots — as TocDoc::Availability objects.
-
#slots ⇒ Array<DateTime>
All individual slots across every availability in the collection.
-
#to_h ⇒ Hash{String => Object}
Returns a plain Hash representation of the collection.
-
#total ⇒ Integer
The total number of available slots in the collection.
Constructor Details
#initialize(data, query: {}, path: '/availabilities.json', client: nil) ⇒ Collection
Returns a new instance of Collection.
28 29 30 31 32 33 |
# File 'lib/toc_doc/models/availability/collection.rb', line 28 def initialize(data, query: {}, path: '/availabilities.json', client: nil) @data = data.dup @query = query @path = path @client = client end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
21 22 23 |
# File 'lib/toc_doc/models/availability/collection.rb', line 21 def path @path end |
#query ⇒ Object (readonly)
Returns the value of attribute query.
21 22 23 |
# File 'lib/toc_doc/models/availability/collection.rb', line 21 def query @query end |
Instance Method Details
#availabilities ⇒ Array<TocDoc::Availability> Also known as: all
All TocDoc::Availability instances that have at least one slot.
Results are memoized and invalidated by #merge_page!.
40 41 42 43 44 |
# File 'lib/toc_doc/models/availability/collection.rb', line 40 def availabilities @availabilities ||= Array(@data['availabilities']) .select { |entry| Array(entry['slots']).any? } .map { |entry| TocDoc::Availability.new(entry) } end |
#booking_url ⇒ String?
Builds a Doctolib booking URL for the current query context.
Requires +booking_slug+ to have been passed as an option to TocDoc::Availability.where. Returns +nil+ when absent.
The URL targets the motive-selection step of the booking funnel, pre-filled with the first practice ID and the visit motive IDs from the original query.
168 169 170 171 172 173 174 175 |
# File 'lib/toc_doc/models/availability/collection.rb', line 168 def booking_url return unless @query[:booking_slug] practice_id = [@query[:practice_ids]].flatten.first "#{TocDoc.api_endpoint}/#{@query[:booking_slug]}/booking/motives" \ "?pid=practice-#{practice_id}" \ "&vmids[]=#{@query[:visit_motive_ids]}" end |
#each {|availability| ... } ⇒ Enumerator
Iterates over TocDoc::Availability instances that have at least one slot.
59 60 61 |
# File 'lib/toc_doc/models/availability/collection.rb', line 59 def each(&) availabilities.each(&) end |
#load_next! ⇒ self
Fetches the next window of availabilities and merges it into this collection.
Uses the +next_slot+ date from the API response as the +start_date+ for the follow-up request.
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/toc_doc/models/availability/collection.rb', line 107 def load_next! raise TocDoc::Error, 'No client available for pagination' unless @client raise StopIteration, 'No more pages available' unless more? next_date = Date.parse(@data['next_slot']).to_s next_page = @client.get(@path, query: @query.merge(start_date: next_date)) @data.delete('next_slot') @data['next_slot'] = next_page['next_slot'] if next_page.key?('next_slot') merge_page!(next_page) end |
#merge_page!(page_data) ⇒ self
Fetches the next window of availabilities (starting the day after the last date in the current collection) and merges them in.
141 142 143 144 145 146 |
# File 'lib/toc_doc/models/availability/collection.rb', line 141 def merge_page!(page_data) @data['availabilities'] = @data.fetch('availabilities', []) + page_data.fetch('availabilities', []) @data['total'] = @data.fetch('total', 0) + page_data.fetch('total', 0) @availabilities = nil self end |
#more? ⇒ Boolean
Returns +true+ when the API has indicated that more results exist beyond the currently loaded pages.
92 93 94 |
# File 'lib/toc_doc/models/availability/collection.rb', line 92 def more? !!@data['next_slot'] end |
#next_slot ⇒ String?
The nearest available appointment slot.
Returns the +next_slot+ value from the API when present (which only occurs when none of the loaded dates have any slots). Otherwise returns the first slot of the first date that has one.
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/toc_doc/models/availability/collection.rb', line 77 def next_slot return @data['next_slot'] if @data.key?('next_slot') Array(@data['availabilities']).each do |entry| slots = Array(entry['slots']) return slots.first unless slots.empty? end nil end |
#raw_availabilities ⇒ Array<TocDoc::Availability>
All date entries — including those with no slots — as TocDoc::Availability objects.
122 123 124 |
# File 'lib/toc_doc/models/availability/collection.rb', line 122 def raw_availabilities Array(@data['availabilities']).map { |entry| TocDoc::Availability.new(entry) } end |
#slots ⇒ Array<DateTime>
All individual slots across every availability in the collection.
51 52 53 |
# File 'lib/toc_doc/models/availability/collection.rb', line 51 def slots availabilities.flat_map(&:slots) end |
#to_h ⇒ Hash{String => Object}
Returns a plain Hash representation of the collection.
The +availabilities+ key contains only dates with slots (filtered), serialised back to plain Hashes.
132 133 134 |
# File 'lib/toc_doc/models/availability/collection.rb', line 132 def to_h @data.merge('availabilities' => availabilities.map(&:to_h)) end |
#total ⇒ Integer
The total number of available slots in the collection.
66 67 68 |
# File 'lib/toc_doc/models/availability/collection.rb', line 66 def total @data['total'] end |