Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix for kigo quote price #463

Merged
merged 4 commits into from
Oct 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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