Skip to content

Commit

Permalink
Merge pull request #463 from roomorama/bugfix/kigo_quote_price
Browse files Browse the repository at this point in the history
Bugfix for kigo quote price
  • Loading branch information
Sharipov Ruslan authored Oct 21, 2016
2 parents 758f922 + e6dd75b commit 4f3657c
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 41 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ how this file is formatted and how the process works.
### Added
- Rentals United: add late check-in / early check-out fees to description_append

### Fixed
- Atleisure: set cleaning fee mapping logic according to #405
- `Kigo::Calendar` now respects to property's `minimum_stay` value if it's more stricter

## [0.12.11] - 2016-10-21
### Added
- Atleisure, Ciirus, Poplidays, Kigo, Waytostay, RentalsUnited: add error.data reporting to Rollbar
- Translations for title, description, t&c, check_in_instructions and
description_append on Roomorama::Property

### Fixed
- Atleisure: set cleaning fee mapping logic according to #405

## [0.12.10] - 2016-10-19
### Fixed
- Poplidays: metadata sync is safe for `nil` availabilities response
Expand Down
6 changes: 6 additions & 0 deletions lib/concierge/suppliers/kigo/calendar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def perform(pricing, availabilities: [], reservations: [])
set_reservations(reservations)

entries.each do |entry|
min_stay = Kigo::Mappers::MinStay.new(
property.data.get("minimum_stay"),
entry.minimum_stay
)

entry.minimum_stay = min_stay.value
calendar.add(entry)
end

Expand Down
25 changes: 25 additions & 0 deletions lib/concierge/suppliers/kigo/mappers/min_stay.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Kigo::Mappers
# It's possible that min_stay value for property and min_stay value for
# calendar entry can be different.
#
# This class solves the problem of determining which min_stay value
# we should use.
#
# This class should be used everywhere where we need to set min_stay values.
class MinStay
attr_reader :prop_min_stay, :cal_min_stay

def initialize(prop_min_stay, cal_min_stay)
@prop_min_stay = prop_min_stay
@cal_min_stay = cal_min_stay
end

# Compare and return the most strict min_stay value.
# Return nil if both prop_min_stay and cal_min_stay are zero
def value
min_stay = [prop_min_stay.to_i, cal_min_stay.to_i].max

min_stay.zero? ? nil : min_stay
end
end
end
29 changes: 15 additions & 14 deletions lib/concierge/suppliers/kigo/mappers/property.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def prepare(property_data, pricing_data)
return Result.error(:no_prices_provided, "Empty or invalid price") unless pricing_mapper.valid?

set_price(pricing_mapper)
set_minimum_stay(pricing_mapper)
set_images

set_deposit
Expand Down Expand Up @@ -73,9 +74,6 @@ def set_base_info
property.check_out_time = info['PROP_COUT_TIME']
property.check_in_instructions = info['PROP_ARRIVAL_SHEET']

# min_stay is set here, but maybe overided with a stricter minimum from pricingSetup
property.minimum_stay = stay_length(info['PROP_STAYTIME_MIN'])

# Kigo properties are available by default, but most of them has a periodical rate
# which covers almost all days. The days which not in periodical rates
# have unavailable availabilities for these days
Expand All @@ -95,12 +93,6 @@ def set_base_info
end
end

# Parse the minimum stay from the given interval,
# or use 1 to statisfy Roomorama's property validation
def stay_length(interval)
Kigo::TimeInterval.new(interval).days || 1
end

def set_description
description = strip(info['PROP_DESCRIPTION']) || strip(info['PROP_SHORTDESCRIPTION'])
area_description = strip(info['PROP_AREADESCRIPTION'])
Expand Down Expand Up @@ -165,6 +157,20 @@ def set_cleaning_service
property.services_cleaning_rate = get_fee_amount(cleaning_fee)
end

def set_minimum_stay(pricing_mapper)
min_stay = Kigo::Mappers::MinStay.new(
stay_length(info['PROP_STAYTIME_MIN']),
pricing_mapper.minimum_stay
)

# Use 1 if min_stay is nil to satisfy Roomorama's property validation
property.minimum_stay = min_stay.value || 1
end

def stay_length(interval)
Kigo::TimeInterval.new(interval).days
end

# STAYLENGTH unit means deposit has different prices for night, week, month
# since Roomorama doesn't support variates of deposit, to be conservative
# we are choosing maximum price
Expand Down Expand Up @@ -194,11 +200,6 @@ def set_price(pricing_mapper)
property.nightly_rate = pricing_mapper.nightly_rate
property.weekly_rate = pricing_mapper.weekly_rate
property.monthly_rate = pricing_mapper.monthly_rate
property.minimum_stay = [
property.minimum_stay.to_i,
pricing_mapper.minimum_stay
].max

end

def code_for(item)
Expand Down
52 changes: 42 additions & 10 deletions spec/lib/concierge/suppliers/kigo/calendar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,50 @@
expect(entry.checkout_allowed).to eq true
end

it 'returns calendar with unavailable dates' do
availabilities.concat([availability, unavailable_availability])
result = subject.perform(nil, availabilities: availabilities)
context "when pricing is empty" do
let(:pricing) { nil }

expect(result).to be_success
context "when property has minimum_stay value" do
let(:property) { create_property(data: { minimum_stay: 17 }) }

it 'uses entry.minimum_stay value from property' do
availabilities.concat([availability, unavailable_availability])
result = subject.perform(pricing, availabilities: availabilities)

expect(result).to be_success

calendar = result.value
available_entry = calendar.entries.find { |entry| entry.date.to_s == availability['DATE'] }
unavailable_entry = calendar.entries.find { |entry| entry.date.to_s == unavailable_availability['DATE'] }

expect(available_entry.available).to eq true
expect(unavailable_entry.available).to eq false

calendar.entries.each do |entry|
expect(entry.minimum_stay).to eq(17)
end
end
end

context "when property hasn't minimum_stay value" do
it 'returns entries with nil min stay' do
availabilities.concat([availability, unavailable_availability])
result = subject.perform(pricing, availabilities: availabilities)

expect(result).to be_success

calendar = result.value
available_entry = calendar.entries.find { |entry| entry.date.to_s == availability['DATE'] }
unavailable_entry = calendar.entries.find { |entry| entry.date.to_s == unavailable_availability['DATE'] }

calendar = result.value
available_entry = calendar.entries.find { |entry| entry.date.to_s == availability['DATE'] }
unavailable_entry = calendar.entries.find { |entry| entry.date.to_s == unavailable_availability['DATE'] }
expect(available_entry.available).to eq true
expect(unavailable_entry.available).to eq false

expect(available_entry.available).to eq true
expect(unavailable_entry.available).to eq false
calendar.entries.each do |entry|
expect(entry.minimum_stay).to be_nil
end
end
end
end
end

Expand All @@ -76,4 +108,4 @@
end

end
end
end
72 changes: 72 additions & 0 deletions spec/lib/concierge/suppliers/kigo/mappers/min_stay_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require 'spec_helper'

RSpec.describe Kigo::Mappers::MinStay do
describe "#value" do
it "selects property's minimum_stay if it's bigger than calendar's minimum_stay" do
prop_min_stay = 20
cal_min_stay = 19

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(20)
end

it "selects calendars's minimum_stay if it's bigger than property's minimum_stay" do
prop_min_stay = 16
cal_min_stay = 17

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(17)
end

it "selects any of minimum_stay values if they equal to each other" do
prop_min_stay = 15
cal_min_stay = 15

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(15)
end

it "selects property's minimum_stay when calendar's one is nil" do
prop_min_stay = 13
cal_min_stay = nil

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(13)
end

it "selects property's minimum_stay when calendar's one is nil" do
prop_min_stay = nil
cal_min_stay = 11

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(11)
end

it "applies .to_i to property's minimum_stay values" do
prop_min_stay = "20"
cal_min_stay = 19

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(20)
end

it "applies .to_i to calendars's minimum_stay values" do
prop_min_stay = 10
cal_min_stay = "19"

min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to eq(19)
end

it "returns error when both minimum_stay values are nil or 0" do
null_values = [nil, 0]

null_values.each do |prop_min_stay|
null_values.each do |cal_min_stay|
min_stay = described_class.new(prop_min_stay, cal_min_stay)
expect(min_stay.value).to be_nil
end
end
end
end
end
57 changes: 43 additions & 14 deletions spec/workers/suppliers/kigo/calendar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
let(:supplier) { create_supplier(name: 'Kigo') }
let(:identifier) { '123' }
let(:host) { create_host(supplier_id: supplier.id, identifier: '14908') }
let!(:property) { create_property(host_id: host.id, identifier: identifier) }
let(:property_attrs) {{ host_id: host.id, identifier: identifier }}
let!(:property) { create_property(property_attrs) }

subject { described_class.new(host, [identifier]) }

Expand Down Expand Up @@ -69,24 +70,52 @@
expect(stats[:unavailable_records]).to eq 0
end

it 'sets only availabilities' do
empty_prices = { 'PRICING' => nil }
allow_any_instance_of(Kigo::Importer).to receive(:fetch_prices) { Result.new(empty_prices) }
allow_any_instance_of(Kigo::Importer).to receive(:fetch_availabilities) { Result.new(availabilities) }
context "when pricing is empty" do
let(:empty_prices) {{ 'PRICING' => nil }}

subject.perform
context "when property has minimum_stay value" do
let(:property_attrs) {{ host_id: host.id, identifier: identifier, data: { minimum_stay: 13, nightly_rate: 10 }}}

sync_process = SyncProcessRepository.last
it 'sets only availabilities' do
allow_any_instance_of(Kigo::Importer).to receive(:fetch_prices) { Result.new(empty_prices) }
allow_any_instance_of(Kigo::Importer).to receive(:fetch_availabilities) { Result.new(availabilities) }

expect(sync_process.host_id).to eq host.id
expect(sync_process.type).to eq 'availabilities'
subject.perform

stats = sync_process.stats
sync_process = SyncProcessRepository.last

expect(stats[:properties_processed]).to eq 1
expect(stats[:available_records]).to eq 1
expect(stats[:unavailable_records]).to eq 7
expect(sync_process.host_id).to eq host.id
expect(sync_process.type).to eq 'availabilities'

stats = sync_process.stats

expect(stats[:properties_processed]).to eq 1
expect(stats[:available_records]).to eq 1
expect(stats[:unavailable_records]).to eq 7
end
end

context "when property has no minimum_stay value" do
let(:property_attrs) {{ host_id: host.id, identifier: identifier, data: { minimum_stay: nil, nightly_rate: 10 }}}

it "doesn't creates an external error" do
allow_any_instance_of(Kigo::Importer).to receive(:fetch_prices) { Result.new(empty_prices) }
allow_any_instance_of(Kigo::Importer).to receive(:fetch_availabilities) { Result.new(availabilities) }

subject.perform

sync_process = SyncProcessRepository.last

expect(sync_process.host_id).to eq host.id
expect(sync_process.type).to eq 'availabilities'

stats = sync_process.stats

expect(stats[:properties_processed]).to eq 1
expect(stats[:available_records]).to eq 1
expect(stats[:unavailable_records]).to eq 7
end
end
end
end

end

0 comments on commit 4f3657c

Please sign in to comment.