diff --git a/base/url_helpers.cpp b/base/url_helpers.cpp index 27090e3a53..a53cc82445 100644 --- a/base/url_helpers.cpp +++ b/base/url_helpers.cpp @@ -13,7 +13,7 @@ string Make(string const & baseUrl, Params const & params) ostringstream os; os << baseUrl; - bool firstParam = true; + bool firstParam = baseUrl.find('?') == string::npos; for (auto const & param : params) { if (firstParam) diff --git a/map/framework.cpp b/map/framework.cpp index 9ac61e2435..523e02f84f 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -862,6 +862,13 @@ void Framework::FillInfoFromFeatureType(FeatureType const & ft, place_page::Info info.SetSponsoredUrl(m_bookingApi->GetBookHotelUrl(baseUrl)); info.SetSponsoredDescriptionUrl(m_bookingApi->GetDescriptionUrl(baseUrl)); info.SetSponsoredReviewUrl(m_bookingApi->GetHotelReviewsUrl(hotelId, baseUrl)); + if (!m_currentBookingAvailabilityParams.IsEmpty()) + { + auto const & url = info.GetSponsoredUrl(); + auto const & urlWithParams = + m_bookingApi->ApplyAvailabilityParams(url, m_currentBookingAvailabilityParams); + info.SetSponsoredUrl(urlWithParams); + } } else if (ftypes::IsOpentableChecker::Instance()(ft)) { @@ -3483,5 +3490,6 @@ void Framework::FilterSearchResultsOnBooking(booking::filter::availability::Para void Framework::OnBookingFilterParamsUpdate(booking::AvailabilityParams const & params) { + m_currentBookingAvailabilityParams = params; m_bookingFilter.OnParamsUpdated(params); } diff --git a/map/framework.hpp b/map/framework.hpp index f0dc08610d..f8f61f6546 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -206,6 +206,7 @@ protected: User m_user; booking::filter::Filter m_bookingFilter; + booking::AvailabilityParams m_currentBookingAvailabilityParams; /// This function will be called by m_storage when latest local files /// is downloaded. diff --git a/map/search_api.cpp b/map/search_api.cpp index 77d19bbe27..d6b6318101 100644 --- a/map/search_api.cpp +++ b/map/search_api.cpp @@ -181,6 +181,9 @@ bool SearchAPI::SearchEverywhere(EverywhereSearchParams const & params) } }); + if (m_sponsoredMode == SponsoredMode::Booking) + m_delegate.OnBookingFilterParamsUpdate(params.m_bookingFilterParams.m_params); + return Search(p, true /* forceSearch */); } diff --git a/partners_api/booking_api.cpp b/partners_api/booking_api.cpp index cd734cc8e6..ae8e51feab 100644 --- a/partners_api/booking_api.cpp +++ b/partners_api/booking_api.cpp @@ -36,6 +36,8 @@ string const kPhotoSmallUrl = "http://aff.bstatic.com/images/hotel/max300/"; string const kSearchBaseUrl = "https://www.booking.com/search.html"; string g_BookingUrlForTesting = ""; +vector const kAvailabilityParamsForUrl = {"checkin", "checkout", "room"}; + bool RunSimpleHttpRequest(bool const needAuth, string const & url, string & result) { HttpClient request(url); @@ -319,6 +321,33 @@ string Api::GetSearchUrl(string const & city, string const & name) const return resultStream.str(); } +string Api::ApplyAvailabilityParams(string const & url, AvailabilityParams const & params) +{ + if (params.IsEmpty()) + return url; + + auto p = params.Get(); + p.erase(remove_if(p.begin(), p.end(), [](url::Param const & param) + { + for (auto const & paramForUrl : kAvailabilityParamsForUrl) + { + // We need to use all numbered rooms, because of this we use find instead of ==. + if (param.m_name.find(paramForUrl) == 0) + return false; + } + return true; + }), p.end()); + + auto const pos = url.find('#'); + + if (pos == string::npos) + return url::Make(url, p); + + string result = url::Make(url.substr(0, pos), p); + result.append(url.substr(pos, url.size() - pos)); + return result; +} + void Api::GetMinPrice(string const & hotelId, string const & currency, GetMinPriceCallback const & fn) const { diff --git a/partners_api/booking_api.hpp b/partners_api/booking_api.hpp index 7509ee628b..a36bec8f73 100644 --- a/partners_api/booking_api.hpp +++ b/partners_api/booking_api.hpp @@ -71,6 +71,7 @@ public: std::string GetDescriptionUrl(std::string const & baseUrl) const; std::string GetHotelReviewsUrl(std::string const & hotelId, std::string const & baseUrl) const; std::string GetSearchUrl(std::string const & city, std::string const & name) const; + std::string ApplyAvailabilityParams(std::string const & url, AvailabilityParams const & params); /// Real-time information methods (used for retrieving rapidly changing information). /// These methods send requests directly to Booking.