Skip to content

Instantly share code, notes, and snippets.

@GustavoCaso
Created July 1, 2016 14:28
Show Gist options
  • Save GustavoCaso/bb4c06abc77f7b82d3e61502e0a16f1b to your computer and use it in GitHub Desktop.
Save GustavoCaso/bb4c06abc77f7b82d3e61502e0a16f1b to your computer and use it in GitHub Desktop.
Error Handling discussion
module Hybridflow
class CRMMessageParser
class Clipboard
attr_reader :message, :context, :error_handler
def self.car_rental_providers
providers = Pathify::CarProvider.all.map{ |p| p.name.try(:downcase).try(:strip) }.compact
providers.empty? ? _car_rental_providers : providers
rescue
_car_rental_providers
end
def self._car_rental_providers
[
'avis',
'dollar',
'interrent',
'national',
'firefly',
'thrifty',
'budget',
'enterprise',
'fox',
'europcar',
'hertz',
'sixt'
]
end
def initialize(message, context)
@message = message
@context = context
@error_handler = ErrorHandlerParser.new(context, message)
check_quotes_integrity
end
delegate :check_errors_for_air_quotes, :check_errors_for_hotel_quotes,
:check_errors_for_car_quotes, :check_quotes_integrity,
to: :error_handler
def flight_options
check_errors_for_air_quotes(parse_flight_options) || parse_flight_options
end
def hotel_options
check_errors_for_hotel_quotes(parse_hotel_options) || parse_hotel_options
end
def car_rental_options
check_errors_for_car_quotes(parse_car_options) || parse_car_options
end
private
def options(key)
message[key].select { |k, v| v['quote'].present? }
end
def parse_car_options
options('car_quotes').each_with_object([]) do |(h, k), array|
page = Nokogiri::HTML(k['quote'])
hash = {}
hash[:id] = k['id']
hash[:segments] = FreeText.car(car_segment(page).flatten)
array << hash
array
end
end
def parse_hotel_options
options('hotel_quotes').each_with_object([]) do |(h, k), array|
page = Nokogiri::HTML(k['quote'])
hash = {}
hash[:id] = k['id']
hash[:segments] = FreeText.hotel(hotel_segment(page))
array << hash
array
end
end
def parse_flight_options
@parse_flight_options ||= options('air_quotes').each_with_object([]) do |(h, k), array|
page = Nokogiri::HTML(k['quote'])
hash = {}
hash[:id] = k['id']
hash[:segments] = []
air_segments(page).each do |seg|
hash[:segments] << AirSegment.air_segment(seg) if seg.count > 1
hash.merge!(AirSegment.fare(seg)) if seg.count == 1
end
array << hash
array
end
end
def car_segment(page)
page_path = car_segment_table(page)
page_path.children.each_with_object([]) do |node, array|
array << node.children.map do |n|
n.text.squish
end
array
end
end
def car_segment_table(page)
page.xpath('/html/body/table[2]/tbody').presence || page.xpath('/html/body/table/tbody')
end
def hotel_segment(page)
if page.xpath('/html/body/table').count > 1
if page.xpath('/html/body/table[2]/tbody/tr/td/table/tbody/tr[1]').text == "HOTEL"
parse_hotel_table(page, '/html/body/table[2]/tbody/tr/td/table/tbody/tr[2]', 1)
else
parse_hotel_table(page, '/html/body/table[2]/tbody', 2)
end
else
if page.xpath('/html/body/table/tbody/tr[1]').text == "HOTEL"
parse_hotel_table(page, '/html/body/table/tbody/tr[2]', 1)
else
parse_hotel_table(page, '/html/body/table/tbody', 2)
end
end
end
def parse_hotel_table(page, xpath, children_count)
hotel_name_row = true
page.xpath(xpath).children.each_with_object([]) do |node, array|
result = if node.children.count == children_count && hotel_name_row
hotel_name_row = false
node.xpath('td[2]').text.squish.presence || node.text.squish
else
node.text.squish if node.text.squish.include?('Rate')
end
array << result if result.present?
array
end
end
def air_segments(page)
page.xpath('/html/body/table/tbody').children.each_with_object([]) do |node, array|
array << node if node.children.count > 1 || node.text.include?('Fare')
array
end.each_slice(2).to_a
end
end
end
end
module Hybridflow
class CRMMessageParser
class Clipboard
class ErrorHandlerParser
class MissingQuotesFromAgent < StandardError; end
class NotValidFormat < StandardError; end
def initialize(context, agent_respond)
@context = context
@agent_respond = agent_respond
end
def check_quotes_integrity
raise MissingQuotesFromAgent, error_quotes_message if quotes_errors.present?
end
['air_quotes', 'hotel_quotes', 'car_quotes'].each do |quote_type|
define_method "check_errors_for_#{quote_type}" do |result|
if options(quote_type).present?
raise NotValidFormat, "The format of the clipboard for #{quote_type} is not compatible" if result.any?{|h| h[:segments].empty?}
end
end
end
private
attr_reader :context, :agent_respond
def quotes_errors
return @error_missing_quote if defined?(@error_missing_quote)
@error_missing_quote = {}
user_request.each do |key, value|
@error_missing_quote[key] = value unless options(key).present? == value
end
@error_missing_quote
end
def error_quotes_message
quotes_errors.map do |key, value|
if value
"The traveller has requested #{key} but no quotes where sent"
else
"The traveller has not requested #{key} but quotes where sent"
end
end.join('\n')
end
def user_request
TicketContextMapper.call(context)
end
def options(key)
agent_respond[key].select { |k, v| v['quote'].present? }
end
class TicketContextMapper < HashMap::Base
from_child :flight do
property :air_quotes, from: :confirmed
end
from_child :hotel do
property :hotel_quotes, from: :confirmed
end
from_child :car_rental do
property :car_quotes, from: :confirmed
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment