Skip to content

Commit

Permalink
Merge pull request #507 from roomorama/release/0.13.0
Browse files Browse the repository at this point in the history
Release/0.13.0
  • Loading branch information
keang authored Nov 2, 2016
2 parents d2b36ee + 8ddb218 commit 0976663
Show file tree
Hide file tree
Showing 120 changed files with 11,188 additions and 3 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ROOMORAMA_SECRET_POPLIDAYS=xxx
ROOMORAMA_SECRET_CIIRUS=xxx
ROOMORAMA_SECRET_SAW=xxx
ROOMORAMA_SECRET_RENTALS_UNITED=xxx
ROOMORAMA_SECRET_AVANTIO=xxx
ROLLBAR_ACCESS_TOKEN=not_used_in_development
CONCIERGE_WEB_APP_SECRET=12345
SERVE_STATIC_ASSETS=true
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
This file summarises the most important changes that went live on each release
of Concierge. Please check the Wiki entry on the release process to understand
how this file is formatted and how the process works.
## [0.13.0] - 2016-11-02
### Added
- Avantio integrations: quote, book, cancel and synchronisation

## [0.12.15] - 2016-11-01
### Added
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ gem 'aws-sdk', '~> 2.3'
gem 'whenever', '~> 0.9', require: false
gem 'sanitize', '~> 4.0.1'
gem 'iso_country_codes', '~> 0.7.4'
gem 'rubyzip', '~> 1.2.0'
gem 'nokogiri', '~> 1.6.7'

group :test do
gem 'rspec', '~> 3.4.0'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
rubyzip (1.2.0)
sanitize (4.0.1)
crass (~> 1.0.2)
nokogiri (>= 1.4.4)
Expand Down Expand Up @@ -152,13 +153,15 @@ DEPENDENCIES
hanami (= 0.7.2)
hanami-model (~> 0.5)
iso_country_codes (~> 0.7.4)
nokogiri (~> 1.6.7)
oauth2
patron (~> 0.5)
pg
rack-handlers (~> 0.7)
rake
rollbar (~> 2.13.3)
rspec (~> 3.4.0)
rubyzip (~> 1.2.0)
sanitize (~> 4.0.1)
savon
unicorn (~> 5.0)
Expand Down
1 change: 1 addition & 0 deletions apps/api/config/environment_variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
- ROOMORAMA_SECRET_CIIRUS
- ROOMORAMA_SECRET_SAW
- ROOMORAMA_SECRET_RENTALS_UNITED
- ROOMORAMA_SECRET_AVANTIO
- ZENDESK_NOTIFY_URL
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
ciirus: %w(url username password),
saw: %w(username password url),
poplidays: %w(url client_key passphrase),
rentalsunited: %w(username password url)
rentalsunited: %w(username password url),
avantio: %w(username password)
})
end
3 changes: 3 additions & 0 deletions apps/api/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
post '/waytostay/quote', to: 'waytostay#quote'
post '/saw/quote', to: 's_a_w#quote'
post '/rentalsunited/quote', to: 'rentals_united#quote'
post '/avantio/quote', to: 'avantio#quote'

post '/jtb/booking', to: 'j_t_b#booking'
post '/atleisure/booking', to: 'at_leisure#booking'
Expand All @@ -17,6 +18,7 @@
post '/saw/booking', to: 's_a_w#booking'
post '/poplidays/booking', to: 'poplidays#booking'
post '/rentalsunited/booking', to: 'rentals_united#booking'
post '/avantio/booking', to: 'avantio#booking'

post '/waytostay/cancel', to: 'waytostay#cancel'
post '/ciirus/cancel', to: 'ciirus#cancel'
Expand All @@ -26,6 +28,7 @@
post '/poplidays/cancel', to: 'poplidays#cancel'
post '/atleisure/cancel', to: 'at_leisure#cancel'
post '/rentalsunited/cancel', to: 'rentals_united#cancel'
post '/avantio/cancel', to: 'avantio#cancel'

post '/checkout', to: 'static#checkout'
get '/kigo/image/:property_id/:image_id', to: 'kigo#image'
22 changes: 22 additions & 0 deletions apps/api/controllers/avantio/booking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require_relative "../booking"

module API::Controllers::Avantio

# +API::Controllers::Avantio::Booking+
#
# Performs create booking for properties from Avantio.
class Booking
include API::Controllers::Booking

params API::Controllers::Params::Booking

def create_booking(params)
credentials = Concierge::Credentials.for(supplier_name)
Avantio::Client.new(credentials).book(params)
end

def supplier_name
Avantio::Client::SUPPLIER_NAME
end
end
end
22 changes: 22 additions & 0 deletions apps/api/controllers/avantio/cancel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require_relative "../cancel"

module API::Controllers::Avantio

# API::Controllers::Avantio::Cancel
#
# Cancels reservation from Avantio.
class Cancel
include API::Controllers::Cancel

params API::Controllers::Params::Cancel

def cancel_reservation(params)
credentials = Concierge::Credentials.for(supplier_name)
Avantio::Client.new(credentials).cancel(params)
end

def supplier_name
Avantio::Client::SUPPLIER_NAME
end
end
end
21 changes: 21 additions & 0 deletions apps/api/controllers/avantio/quote.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require_relative "../quote"

module API::Controllers::Avantio
# API::Controllers::Avantio::Quote
#
# Performs booking quotations for properties from Avantio.
class Quote
include API::Controllers::Quote

params API::Controllers::Params::Quote

def quote_price(params)
credentials = Concierge::Credentials.for(supplier_name)
Avantio::Client.new(credentials).quote(params)
end

def supplier_name
Avantio::Client::SUPPLIER_NAME
end
end
end
3 changes: 2 additions & 1 deletion apps/api/middlewares/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class Secrets
"/waytostay" => ENV["ROOMORAMA_SECRET_WAYTOSTAY"],
"/ciirus" => ENV["ROOMORAMA_SECRET_CIIRUS"],
"/saw" => ENV["ROOMORAMA_SECRET_SAW"],
"/rentalsunited" => ENV["ROOMORAMA_SECRET_RENTALS_UNITED"]
"/rentalsunited" => ENV["ROOMORAMA_SECRET_RENTALS_UNITED"],
"/avantio" => ENV["ROOMORAMA_SECRET_AVANTIO"]
}

attr_reader :mapping
Expand Down
168 changes: 168 additions & 0 deletions apps/workers/suppliers/avantio/availabilities.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
module Workers::Suppliers::Avantio
# +Workers::Suppliers::Avantio::Availabilities+
#
# Performs properties availabilities synchronisation with supplier
# This is aggregated worker so it performs sync for all the hosts.

# Avantio provides all information required for sync by files and
# updates them with different frequency. This frequency should affect the worker
# schedule.
# Update frequency for appropriate files:
# - rates: every day
# - occupational rules: several times a week
# - availabilities: every day or even more often
class Availabilities
# Count of days
PERIOD_SYNC = 365

attr_reader :supplier

def initialize(supplier)
@supplier = supplier
end

def perform

rates = new_context { fetch_rates }
return unless rates.success?
rates = rates.value

availabilities = fetch_availabilities
return unless availabilities.success?
availabilities = availabilities.value

occupational_rules = fetch_occupational_rules
return unless occupational_rules.success?
occupational_rules = occupational_rules.value

hosts.each do |host|
perform_for_host(host, rates, availabilities, occupational_rules)
end
end

private

# The method extracted only for specs because RSpec doesn't allow expect the result for
# several instances of the same class.
def finish_sync(sync)
sync.finish!
end

def perform_for_host(host, rates, availabilities, occupational_rules)
identifiers = all_identifiers(host)
synchronisation = Workers::CalendarSynchronisation.new(host)

identifiers.each do |property_id|

synchronisation.start(property_id) do

rate = rates[property_id]
unless rate
message = "Rate for property `#{property_id}` not found"
augment_context_error(message)
next Result.error(:rate_not_found, message)
end

availability = availabilities[property_id]
unless availability
message = "Availability for property `#{property_id}` not found"
augment_context_error(message)
next Result.error(:availability_not_found, message)
end

rule = occupational_rules[availability.occupational_rule_id]
unless rule
message = "Occupational rule for property `#{property_id}` not found"
augment_context_error(message)
next Result.error(:rule_not_found, message)
end

roomorama_calendar = mapper(property_id, rate, availability, rule).build
Result.new(roomorama_calendar)
end
end
finish_sync(synchronisation)
end

def new_context
Concierge.context = Concierge::Context.new(type: "batch")

message = Concierge::Context::Message.new(
label: 'Aggregated Sync',
message: "Started aggregated metadata sync for `#{supplier}`",
backtrace: caller
)

Concierge.context.augment(message)
yield
end

def failed_sync(message)
yield.tap do |result|
unless result.success?
announce_error(message, result)
end
end
end

def fetch_rates
message = 'Failed to perform the `#fetch_rates` operation'
failed_sync(message) { importer.fetch_rates }
end

def fetch_availabilities
message = 'Failed to perform the `#fetch_availabilities` operation'
failed_sync(message) { importer.fetch_availabilities }
end

def fetch_occupational_rules
message = 'Failed to perform the `#fetch_occupational_rules` operation'
failed_sync(message) { importer.fetch_occupational_rules }
end

def all_identifiers(host)
PropertyRepository.from_host(host).only(:identifier).map(&:identifier)
end

def mapper(property_id, rate, availability, rule)
::Avantio::Mappers::RoomoramaCalendar.new(property_id, rate, availability, rule, PERIOD_SYNC)
end

def hosts
HostRepository.from_supplier(supplier)
end

def importer
@importer ||= ::Avantio::Importer.new(Concierge::Credentials.for(::Avantio::Client::SUPPLIER_NAME))
end

def augment_context_error(message)
message = {
label: 'Synchronisation Failure',
message: message,
backtrace: caller
}
context = Concierge::Context::Message.new(message)
Concierge.context.augment(context)
end

def announce_error(message, result)
augment_context_error(message)

Concierge::Announcer.trigger(Concierge::Errors::EXTERNAL_ERROR, {
operation: 'sync',
supplier: Avantio::Client::SUPPLIER_NAME,
code: result.error.code,
description: result.error.data,
context: Concierge.context.to_h,
happened_at: Time.now
})
end
end
end

# listen supplier worker
Concierge::Announcer.on('availabilities.Avantio') do |supplier, args|
Workers::Suppliers::Avantio::Availabilities.new(supplier).perform
Result.new({})
end
Loading

0 comments on commit 0976663

Please sign in to comment.