Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/jni/com/mapswithme/maps/Framework.cpp7
-rw-r--r--android/jni/com/mapswithme/maps/Framework.hpp11
-rw-r--r--android/jni/com/mapswithme/maps/Sponsored.cpp20
-rw-r--r--iphone/Maps/UI/PlacePage/MWMPlacePageData.mm19
-rw-r--r--map/map_tests/booking_filter_test.cpp2
-rw-r--r--partners_api/CMakeLists.txt2
-rw-r--r--partners_api/booking_api.cpp160
-rw-r--r--partners_api/booking_api.hpp61
-rw-r--r--partners_api/booking_availability_params.cpp6
-rw-r--r--partners_api/booking_availability_params.hpp2
-rw-r--r--partners_api/booking_block_params.cpp60
-rw-r--r--partners_api/booking_block_params.hpp33
-rw-r--r--partners_api/booking_params_base.hpp16
-rw-r--r--partners_api/partners_api_tests/booking_tests.cpp73
-rw-r--r--tools/python/ResponseProvider.py14
-rw-r--r--tools/python/jsons.py74
-rw-r--r--xcode/partners_api/partners_api.xcodeproj/project.pbxproj8
17 files changed, 433 insertions, 135 deletions
diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp
index 23f3b9b04a..1d82cc1975 100644
--- a/android/jni/com/mapswithme/maps/Framework.cpp
+++ b/android/jni/com/mapswithme/maps/Framework.cpp
@@ -11,6 +11,7 @@
#include "partners_api/ads_engine.hpp"
#include "partners_api/banner.hpp"
+#include "partners_api/booking_block_params.hpp"
#include "partners_api/mopub_ads.hpp"
#include "partners_api/megafon_countries.hpp"
@@ -507,12 +508,12 @@ place_page::Info & Framework::GetPlacePageInfo()
}
void Framework::RequestBookingMinPrice(JNIEnv * env, jobject policy,
- string const & hotelId, string const & currencyCode,
- booking::GetMinPriceCallback const & callback)
+ booking::BlockParams const & params,
+ booking::BlockAvailabilityCallback const & callback)
{
auto const bookingApi = m_work.GetBookingApi(ToNativeNetworkPolicy(env, policy));
if (bookingApi)
- bookingApi->GetMinPrice(hotelId, currencyCode, callback);
+ bookingApi->GetBlockAvailability(params, callback);
}
void Framework::RequestBookingInfo(JNIEnv * env, jobject policy,
diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp
index b7fed20c86..eaeaa50f63 100644
--- a/android/jni/com/mapswithme/maps/Framework.hpp
+++ b/android/jni/com/mapswithme/maps/Framework.hpp
@@ -16,6 +16,7 @@
#include "local_ads/event.hpp"
+#include "partners_api/booking_api.hpp"
#include "partners_api/locals_api.hpp"
#include "platform/country_defines.hpp"
@@ -40,6 +41,11 @@ namespace search
struct EverywhereSearchParams;
}
+namespace booking
+{
+struct BlockParams;
+}
+
namespace android
{
class Framework
@@ -175,9 +181,8 @@ namespace android
void SetPlacePageInfo(place_page::Info const & info);
place_page::Info & GetPlacePageInfo();
- void RequestBookingMinPrice(JNIEnv * env, jobject policy,
- std::string const & hotelId, std::string const & currency,
- booking::GetMinPriceCallback const & callback);
+ void RequestBookingMinPrice(JNIEnv * env, jobject policy, booking::BlockParams const & params,
+ booking::BlockAvailabilityCallback const & callback);
void RequestBookingInfo(JNIEnv * env, jobject policy,
std::string const & hotelId, std::string const & lang,
booking::GetHotelInfoCallback const & callback);
diff --git a/android/jni/com/mapswithme/maps/Sponsored.cpp b/android/jni/com/mapswithme/maps/Sponsored.cpp
index c2ff6f1e86..9c44b84e0a 100644
--- a/android/jni/com/mapswithme/maps/Sponsored.cpp
+++ b/android/jni/com/mapswithme/maps/Sponsored.cpp
@@ -1,9 +1,12 @@
-#include "Framework.hpp"
+#include "com/mapswithme/maps/Framework.hpp"
#include "com/mapswithme/core/jni_helper.hpp"
#include "com/mapswithme/platform/Platform.hpp"
+
#include "map/place_page_info.hpp"
+
#include "partners_api/booking_api.hpp"
+#include "partners_api/booking_block_params.hpp"
#include <chrono>
#include <functional>
@@ -142,16 +145,21 @@ JNIEXPORT void JNICALL Java_com_mapswithme_maps_widget_placepage_Sponsored_nativ
g_lastRequestedHotelId = hotelId;
std::string const code = jni::ToNativeString(env, currencyCode);
-
+ auto params = booking::BlockParams::MakeDefault();
+ params.m_hotelId = hotelId;
+ params.m_currency = code;
g_framework->RequestBookingMinPrice(
- env, policy, hotelId, code,
- [](std::string const hotelId, std::string const price, std::string const currency) {
+ env, policy, params, [](std::string const & hotelId, booking::Blocks const & blocks) {
if (g_lastRequestedHotelId != hotelId)
return;
JNIEnv * env = jni::GetEnv();
- env->CallStaticVoidMethod(g_sponsoredClass, g_priceCallback, jni::ToJavaString(env, hotelId),
- jni::ToJavaString(env, price), jni::ToJavaString(env, currency));
+ auto const price = blocks.m_totalMinPrice == BlockInfo::kIncorrectPrice
+ ? ""
+ : std::to_string(blocks.m_totalMinPrice);
+ env->CallStaticVoidMethod(g_sponsoredClass, g_priceCallback,
+ jni::ToJavaString(env, hotelId), jni::ToJavaString(env, price),
+ jni::ToJavaString(env, blocks.m_currency));
});
}
diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm
index 958f258464..32828608f1 100644
--- a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm
+++ b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm
@@ -16,9 +16,12 @@
#include "platform/preferred_languages.hpp"
#include "partners_api/booking_api.hpp"
+#include "partners_api/booking_block_params.hpp"
#include "3party/opening_hours/opening_hours.hpp"
+#include <string>
+
using namespace place_page;
namespace
@@ -579,16 +582,19 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
auto const func = [self, label, currency](std::string const & hotelId,
- std::string const & minPrice,
- std::string const & priceCurrency) {
- if (currency != priceCurrency)
+ booking::Blocks const & blocks) {
+ if (currency != blocks.m_currency)
return;
NSNumberFormatter * decimalFormatter = [[NSNumberFormatter alloc] init];
decimalFormatter.numberStyle = NSNumberFormatterDecimalStyle;
+ auto const price = blocks.m_totalMinPrice == booking::BlockInfo::kIncorrectPrice
+ ? ""
+ : std::to_string(blocks.m_totalMinPrice);
+
NSNumber * currencyNumber = [decimalFormatter
- numberFromString:[@(minPrice.c_str())
+ numberFromString:[@(price.c_str())
stringByReplacingOccurrencesOfString:@"."
withString:decimalFormatter
.decimalSeparator]];
@@ -601,7 +607,10 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
});
};
- api->GetMinPrice(self.sponsoredId.UTF8String, currency, func);
+ auto params = booking::BlockParams::MakeDefault();
+ params.m_hotelId = self.sponsoredId.UTF8String;
+ params.m_currency = currency;
+ api->GetBlockAvailability(params, func);
});
}
diff --git a/map/map_tests/booking_filter_test.cpp b/map/map_tests/booking_filter_test.cpp
index 1b03251172..9223fa1065 100644
--- a/map/map_tests/booking_filter_test.cpp
+++ b/map/map_tests/booking_filter_test.cpp
@@ -35,7 +35,7 @@ public:
protected:
TestMwmEnvironment()
{
- booking::SetBookingUrlForTesting("http://localhost:34568/booking/min_price");
+ booking::SetBookingUrlForTesting("http://localhost:34568/booking");
}
~TestMwmEnvironment()
diff --git a/partners_api/CMakeLists.txt b/partners_api/CMakeLists.txt
index b8a474c7f3..d7f0e3f53a 100644
--- a/partners_api/CMakeLists.txt
+++ b/partners_api/CMakeLists.txt
@@ -13,6 +13,8 @@ set(
booking_api.hpp
booking_availability_params.cpp
booking_availability_params.hpp
+ booking_block_params.cpp
+ booking_block_params.hpp
booking_params_base.hpp
facebook_ads.cpp
facebook_ads.hpp
diff --git a/partners_api/booking_api.cpp b/partners_api/booking_api.cpp
index dd4732d364..ad92a1548d 100644
--- a/partners_api/booking_api.cpp
+++ b/partners_api/booking_api.cpp
@@ -30,7 +30,7 @@ using namespace std::chrono;
namespace
{
string const kBookingApiBaseUrlV1 = "https://distribution-xml.booking.com/json/bookings";
-string const kBookingApiBaseUrlV2 = "https://distribution-xml.booking.com/2.0/json/";
+string const kBookingApiBaseUrlV2 = "https://distribution-xml.booking.com/2.0/json";
string const kExtendedHotelInfoBaseUrl = "https://hotels.maps.me/getDescription";
string const kPhotoOriginalUrl = "http://aff.bstatic.com/images/hotel/max500/";
string const kPhotoSmallUrl = "http://aff.bstatic.com/images/hotel/max300/";
@@ -231,43 +231,123 @@ void FillHotelInfo(string const & src, HotelInfo & info)
info.m_reviews = ParseReviews(reviewsArray);
}
-void FillPriceAndCurrency(string const & src, string const & currency, string & minPrice,
- string & priceCurrency)
+void FillPriceAndCurrency(json_t * src, string const & currency, BlockInfo & result)
{
- my::Json root(src.c_str());
- if (!json_is_array(root.get()))
- MYTHROW(my::Json::Exception, ("The answer must contain a json array."));
- size_t const rootSize = json_array_size(root.get());
+ FromJSONObject(src, "currency", result.m_currency);
+ FromJSONObject(src, "price", result.m_minPrice);
- if (rootSize == 0)
+ if (currency.empty() || result.m_currency == currency)
return;
- // Read default hotel price and currency.
- auto obj = json_array_get(root.get(), 0);
- FromJSONObject(obj, "min_price", minPrice);
- FromJSONObject(obj, "currency_code", priceCurrency);
-
- if (currency.empty() || priceCurrency == currency)
+ // Try to get price in requested currency.
+ json_t * other = json_object_get(src, "other_currency");
+ if (!json_is_object(other))
return;
- // Try to get price in requested currency.
- json_t * arr = json_object_get(obj, "other_currency");
- if (arr == nullptr || !json_is_array(arr))
+ string otherCurrency;
+ FromJSONObject(other, "currency", otherCurrency);
+ if (otherCurrency == currency)
+ {
+ result.m_currency = otherCurrency;
+ FromJSONObject(other, "price", result.m_minPrice);
return;
+ }
+}
+
+BlockInfo MakeBlock(json_t * src, string const & currency)
+{
+ BlockInfo result;
+
+ FromJSONObject(src, "block_id", result.m_blockId);
+ FromJSONObject(src, "name", result.m_name);
+ FromJSONObject(src, "room_description", result.m_description);
+ FromJSONObject(src, "max_occupancy", result.m_maxOccupancy);
+ FromJSONObject(src, "breakfast_included", result.m_breakfastIncluded);
+ FromJSONObject(src, "deposit_required", result.m_depositRequired);
- size_t sz = json_array_size(arr);
- string code;
+ auto minPriceRoot = json_object_get(src, "min_price");
+ if (!json_is_object(minPriceRoot))
+ MYTHROW(my::Json::Exception, ("The min_price must contain a json object."));
+
+ FillPriceAndCurrency(minPriceRoot, currency, result);
+
+ auto photosArray = json_object_get(src, "photos");
+ size_t sz = json_array_size(photosArray);
+ string photoUrl;
for (size_t i = 0; i < sz; ++i)
{
- auto el = json_array_get(arr, i);
- FromJSONObject(el, "currency_code", code);
- if (code == currency)
+ auto photoItem = json_array_get(photosArray, i);
+ FromJSONObject(photoItem, "url_original", photoUrl);
+ result.m_photos.emplace_back(photoUrl);
+ }
+
+ Deals deals;
+ bool lastMinuteDeal = false;
+ FromJSONObjectOptionalField(src, "is_last_minute_deal", lastMinuteDeal);
+ if (lastMinuteDeal)
+ {
+ deals.m_types.emplace_back(Deals::Type::LastMinute);
+ FromJSONObject(src, "last_minute_deal_percentage", deals.m_discount);
+ }
+ bool smartDeal = false;
+ FromJSONObjectOptionalField(src, "is_smart_deal", smartDeal);
+ if (smartDeal)
+ deals.m_types.emplace_back(Deals::Type::Smart);
+
+ string refundableUntil;
+ auto refundableUntilObject = json_object_get(src, "refundable_until");
+ if (json_is_string(refundableUntilObject))
+ {
+ FromJSON(refundableUntilObject, refundableUntil);
+
+ if (!refundableUntil.empty())
{
- priceCurrency = code;
- FromJSONObject(el, "min_price", minPrice);
- break;
+ istringstream ss(refundableUntil);
+ tm t = {};
+ ss >> base::get_time(&t, "%Y-%m-%d %H:%M:%S");
+ if (ss.fail())
+ LOG(LWARNING, ("Incorrect refundable_until date =", refundableUntil));
+ else
+ result.m_refundableUntil = system_clock::from_time_t(mktime(&t));
}
}
+
+ return result;
+}
+
+void FillBlocks(string const & src, string const & currency, Blocks & blocks)
+{
+ my::Json root(src.c_str());
+ if (!json_is_object(root.get()))
+ MYTHROW(my::Json::Exception, ("The answer must contain a json object."));
+
+ auto rootArray = json_object_get(root.get(), "result");
+ if (!json_is_array(rootArray))
+ MYTHROW(my::Json::Exception, ("The \"result\" field must contain a json array."));
+
+ size_t const rootSize = json_array_size(rootArray);
+ ASSERT_LESS(rootSize, 2, ("Several hotels is not supported in this method"));
+ if (rootSize == 0)
+ return;
+
+ auto rootItem = json_array_get(rootArray, 0);
+ if (!json_is_object(rootItem))
+ MYTHROW(my::Json::Exception, ("The root item must contain a json object."));
+
+ auto blocksArray = json_object_get(rootItem, "block");
+ if (!json_is_array(blocksArray))
+ MYTHROW(my::Json::Exception, ("The \"block\" field must contain a json array."));
+
+ size_t const blocksSize = json_array_size(blocksArray);
+ for (size_t i = 0; i < blocksSize; ++i)
+ {
+ auto block = json_array_get(blocksArray, i);
+
+ if (!json_is_object(block))
+ MYTHROW(my::Json::Exception, ("The block item must contain a json object."));
+
+ blocks.Add(MakeBlock(block, currency));
+ }
}
void FillHotelIds(string const & src, vector<std::string> & ids)
@@ -345,6 +425,14 @@ bool RawApi::HotelAvailability(AvailabilityParams const & params, string & resul
return RunSimpleHttpRequest(true, url, result);
}
+// static
+bool RawApi::BlockAvailability(BlockParams const & params, string & result)
+{
+ string url = MakeApiUrlV2("blockAvailability", params.Get());
+
+ return RunSimpleHttpRequest(true, url, result);
+}
+
string Api::GetBookHotelUrl(string const & baseUrl) const
{
ASSERT(!baseUrl.empty(), ());
@@ -407,31 +495,29 @@ string Api::ApplyAvailabilityParams(string const & url, AvailabilityParams const
return ApplyAvailabilityParamsUniversal(url, params);
}
-void Api::GetMinPrice(string const & hotelId, string const & currency,
- GetMinPriceCallback const & fn) const
+void Api::GetBlockAvailability(BlockParams const & params,
+ BlockAvailabilityCallback const & fn) const
{
- GetPlatform().RunTask(Platform::Thread::Network, [hotelId, currency, fn]()
+ GetPlatform().RunTask(Platform::Thread::Network, [params, fn]()
{
- string minPrice;
- string priceCurrency;
string httpResult;
- if (!RawApi::GetHotelAvailability(hotelId, currency, httpResult))
+ if (!RawApi::BlockAvailability(params, httpResult))
{
- fn(hotelId, minPrice, priceCurrency);
+ fn(params.m_hotelId, {});
return;
}
+ Blocks blocks;
try
{
- FillPriceAndCurrency(httpResult, currency, minPrice, priceCurrency);
+ FillBlocks(httpResult, params.m_currency, blocks);
}
catch (my::Json::Exception const & e)
{
LOG(LERROR, (e.Msg()));
- minPrice.clear();
- priceCurrency.clear();
+ blocks = {};
}
- fn(hotelId, minPrice, priceCurrency);
+ fn(params.m_hotelId, blocks);
});
}
@@ -456,7 +542,7 @@ void Api::GetHotelInfo(string const & hotelId, string const & lang,
}
catch (my::Json::Exception const & e)
{
- LOG(LERROR, ("Failed to parse json:", hotelId, result, e.what()));
+ LOG(LINFO, ("Failed to parse json:", hotelId, result, e.what()));
ClearHotelInfo(info);
}
diff --git a/partners_api/booking_api.hpp b/partners_api/booking_api.hpp
index 5c4302c3b6..f35d295003 100644
--- a/partners_api/booking_api.hpp
+++ b/partners_api/booking_api.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "partners_api/booking_availability_params.hpp"
+#include "partners_api/booking_block_params.hpp"
#include "platform/safe_callback.hpp"
@@ -48,6 +49,59 @@ struct HotelInfo
uint32_t m_scoreCount = 0;
};
+struct Deals
+{
+ enum Type
+ {
+ /// Good price.
+ Smart,
+ /// Sale with discount in percent from base price.
+ LastMinute
+ };
+
+ std::vector<Type> m_types;
+ uint8_t m_discount = 0;
+};
+
+struct BlockInfo
+{
+ static double constexpr kIncorrectPrice = std::numeric_limits<double>::max();
+ std::string m_blockId;
+ std::string m_name;
+ std::string m_description;
+ uint8_t m_maxOccupancy = 0;
+ double m_minPrice = kIncorrectPrice;
+ std::string m_currency;
+ std::vector<std::string> m_photos;
+ Deals m_deals;
+ std::chrono::time_point<std::chrono::system_clock> m_refundableUntil;
+ bool m_breakfastIncluded = false;
+ bool m_depositRequired = false;
+};
+
+struct Blocks
+{
+ void Add(BlockInfo && block)
+ {
+ if (block.m_minPrice < m_totalMinPrice)
+ {
+ m_totalMinPrice = block.m_minPrice;
+ m_currency = block.m_currency;
+ }
+ if (block.m_deals.m_discount > m_maxDiscount)
+ m_maxDiscount = block.m_deals.m_discount;
+
+ m_blocks.emplace_back(block);
+ }
+
+ double m_totalMinPrice = BlockInfo::kIncorrectPrice;
+ std::string m_currency;
+
+ uint8_t m_maxDiscount = 0;
+
+ std::vector<BlockInfo> m_blocks;
+};
+
class RawApi
{
public:
@@ -56,9 +110,11 @@ public:
static bool GetExtendedInfo(std::string const & hotelId, std::string const & lang, std::string & result);
// Booking Api v2 methods:
static bool HotelAvailability(AvailabilityParams const & params, std::string & result);
+ static bool BlockAvailability(BlockParams const & params, string & result);
};
-using GetMinPriceCallback = platform::SafeCallback<void(std::string const & hotelId, std::string const & price, std::string const & currency)>;
+using BlockAvailabilityCallback =
+ platform::SafeCallback<void(std::string const & hotelId, Blocks const & blocks)>;
using GetHotelInfoCallback = platform::SafeCallback<void(HotelInfo const & hotelInfo)>;
// NOTE: this callback will be called on the network thread.
using GetHotelAvailabilityCallback = std::function<void(std::vector<std::string> hotelIds)>;
@@ -79,8 +135,7 @@ public:
/// Real-time information methods (used for retrieving rapidly changing information).
/// These methods send requests directly to Booking.
- void GetMinPrice(std::string const & hotelId, std::string const & currency,
- GetMinPriceCallback const & fn) const;
+ void GetBlockAvailability(BlockParams const & params, BlockAvailabilityCallback const & fn) const;
/// NOTE: callback will be called on the network thread.
void GetHotelAvailability(AvailabilityParams const & params,
diff --git a/partners_api/booking_availability_params.cpp b/partners_api/booking_availability_params.cpp
index 341e4d32da..506b764a13 100644
--- a/partners_api/booking_availability_params.cpp
+++ b/partners_api/booking_availability_params.cpp
@@ -1,5 +1,4 @@
#include "partners_api/booking_availability_params.hpp"
-#include "partners_api/utils.hpp"
#include "base/string_utils.hpp"
@@ -9,11 +8,6 @@ using namespace base;
namespace
{
-std::string FormatTime(booking::AvailabilityParams::Time p)
-{
- return partners_api::FormatTime(p, "%Y-%m-%d");
-}
-
bool IsAcceptedByFilter(booking::AvailabilityParams::UrlFilter const & filter,
std::string const & value)
{
diff --git a/partners_api/booking_availability_params.hpp b/partners_api/booking_availability_params.hpp
index 3f3bc26db9..7d29c742aa 100644
--- a/partners_api/booking_availability_params.hpp
+++ b/partners_api/booking_availability_params.hpp
@@ -37,8 +37,6 @@ struct AvailabilityParams : public ParamsBase
int8_t m_ageOfChild = kNoChildren;
};
- using Clock = std::chrono::system_clock;
- using Time = Clock::time_point;
using Hotels = std::vector<std::string>;
using Rooms = std::vector<Room>;
using Stars = std::vector<std::string>;
diff --git a/partners_api/booking_block_params.cpp b/partners_api/booking_block_params.cpp
new file mode 100644
index 0000000000..bcd98b4548
--- /dev/null
+++ b/partners_api/booking_block_params.cpp
@@ -0,0 +1,60 @@
+#include "partners_api/booking_block_params.hpp"
+
+#include "base/string_utils.hpp"
+
+using namespace base;
+
+namespace booking
+{
+// static
+BlockParams BlockParams::MakeDefault()
+{
+ BlockParams result;
+ // Use tomorrow and day after tomorrow by default.
+ result.m_checkin = Clock::now() + std::chrono::hours(24);
+ result.m_checkout = Clock::now() + std::chrono::hours(48);
+ // Information about sales by default.
+ result.m_extras = {"deal_smart", "deal_lastm", "photos"};
+
+ return result;
+}
+
+url::Params BlockParams::Get() const
+{
+ url::Params params = {{"hotel_ids", m_hotelId},
+ {"checkin", FormatTime(m_checkin)},
+ {"checkout", FormatTime(m_checkout)}};
+
+ if (!m_currency.empty())
+ params.emplace_back("currency", m_currency);
+
+ if (!m_extras.empty())
+ params.emplace_back("extras", strings::JoinStrings(m_extras, ','));
+
+ if (!m_language.empty())
+ params.emplace_back("language", m_language);
+
+ return params;
+}
+
+bool BlockParams::IsEmpty() const
+{
+ return m_checkin == Time() || m_checkout == Time();
+}
+
+bool BlockParams::Equals(ParamsBase const & rhs) const
+{
+ return rhs.Equals(*this);
+}
+
+bool BlockParams::Equals(BlockParams const & rhs) const
+{
+ return m_checkin == rhs.m_checkin && m_checkout == rhs.m_checkout &&
+ m_currency == rhs.m_currency && m_extras == rhs.m_extras && m_language == rhs.m_language;
+}
+
+void BlockParams::Set(ParamsBase const & src)
+{
+ src.CopyTo(*this);
+}
+} // namepace booking \ No newline at end of file
diff --git a/partners_api/booking_block_params.hpp b/partners_api/booking_block_params.hpp
new file mode 100644
index 0000000000..836cfbfc49
--- /dev/null
+++ b/partners_api/booking_block_params.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "partners_api/booking_params_base.hpp"
+
+#include "base/url_helpers.hpp"
+
+#include <string>
+#include <vector>
+
+namespace booking
+{
+struct BlockParams : public ParamsBase
+{
+ using Extras = std::vector<std::string>;
+
+ static BlockParams MakeDefault();
+
+ base::url::Params Get() const;
+
+ // ParamsBase overrides:
+ bool IsEmpty() const override;
+ bool Equals(ParamsBase const & rhs) const override;
+ bool Equals(BlockParams const & lhs) const override;
+ void Set(ParamsBase const & src) override;
+
+ std::string m_hotelId;
+ std::string m_currency;
+ Time m_checkin;
+ Time m_checkout;
+ Extras m_extras;
+ std::string m_language;
+};
+} // namespce booking
diff --git a/partners_api/booking_params_base.hpp b/partners_api/booking_params_base.hpp
index a740197b34..c2c275662b 100644
--- a/partners_api/booking_params_base.hpp
+++ b/partners_api/booking_params_base.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "partners_api/utils.hpp"
+
#include "base/macros.hpp"
#include <exception>
@@ -7,9 +9,18 @@
namespace booking
{
struct AvailabilityParams;
+struct BlockParams;
struct ParamsBase
{
+ using Clock = std::chrono::system_clock;
+ using Time = Clock::time_point;
+
+ static std::string FormatTime(Time p)
+ {
+ return partners_api::FormatTime(p, "%Y-%m-%d");
+ }
+
virtual ~ParamsBase() = default;
virtual bool IsEmpty() const = 0;
@@ -21,6 +32,11 @@ struct ParamsBase
return false;
}
+ virtual bool Equals(BlockParams const & lhs) const
+ {
+ return false;
+ }
+
template <typename T>
void CopyTo(T & dest) const
{
diff --git a/partners_api/partners_api_tests/booking_tests.cpp b/partners_api/partners_api_tests/booking_tests.cpp
index fdf741e2b8..5491a9c21a 100644
--- a/partners_api/partners_api_tests/booking_tests.cpp
+++ b/partners_api/partners_api_tests/booking_tests.cpp
@@ -16,7 +16,7 @@ class AsyncGuiThreadBooking : public AsyncGuiThread
public:
AsyncGuiThreadBooking()
{
- SetBookingUrlForTesting("http://localhost:34568/booking/min_price");
+ SetBookingUrlForTesting("http://localhost:34568/booking");
}
~AsyncGuiThreadBooking() override
@@ -55,66 +55,53 @@ UNIT_TEST(Booking_HotelAvailability)
LOG(LINFO, (result));
}
-UNIT_CLASS_TEST(AsyncGuiThreadBooking, Booking_GetMinPrice)
+UNIT_CLASS_TEST(AsyncGuiThreadBooking, Booking_GetBlockAvailability)
{
- string const kHotelId = "0"; // Internal hotel id for testing.
+ auto params = BlockParams::MakeDefault();
+ params.m_hotelId = "0"; // Internal hotel id for testing.
Api api;
{
- string price;
+ double price = std::numeric_limits<double>::max();
string currency;
string hotelId;
- api.GetMinPrice(kHotelId, "" /* default currency */,
- [&hotelId, &price, &currency](string const & id, string const & val, string const & curr) {
- hotelId = id;
- price = val;
- currency = curr;
- testing::Notify();
- });
+ api.GetBlockAvailability(params, [&hotelId, &price, &currency](std::string const & id,
+ Blocks const & blocks)
+ {
+ hotelId = id;
+ price = blocks.m_totalMinPrice;
+ currency = blocks.m_currency;
+ testing::Notify();
+ });
testing::Wait();
- TEST_EQUAL(hotelId, kHotelId, ());
- TEST(!price.empty(), ());
+ TEST_EQUAL(hotelId, params.m_hotelId, ());
+ TEST_NOT_EQUAL(price, std::numeric_limits<double>::max(), ());
TEST(!currency.empty(), ());
- TEST_EQUAL(currency, "USD", ());
+ TEST_EQUAL(currency, "EUR", ());
}
{
- string price;
+ auto params = BlockParams::MakeDefault();
+ params.m_hotelId = "0"; // Internal hotel id for testing.
+ params.m_currency = "RUB";
+ double price = std::numeric_limits<double>::max();
string currency;
string hotelId;
- api.GetMinPrice(kHotelId, "RUB", [&hotelId, &price, &currency](string const & id, string const & val, string const & curr)
- {
- hotelId = id;
- price = val;
- currency = curr;
- testing::Notify();
- });
+ api.GetBlockAvailability(params, [&hotelId, &price, &currency](std::string const & id,
+ Blocks const & blocks)
+ {
+ hotelId = id;
+ price = blocks.m_totalMinPrice;
+ currency = blocks.m_currency;
+ testing::Notify();
+ });
testing::Wait();
- TEST_EQUAL(hotelId, kHotelId, ());
- TEST(!price.empty(), ());
+ TEST_EQUAL(hotelId, params.m_hotelId, ());
+ TEST_NOT_EQUAL(price, std::numeric_limits<double>::max(), ());
TEST(!currency.empty(), ());
TEST_EQUAL(currency, "RUB", ());
}
-
- {
- string price;
- string currency;
- string hotelId;
- api.GetMinPrice(kHotelId, "ISK", [&hotelId, &price, &currency](string const & id, string const & val, string const & curr)
- {
- hotelId = id;
- price = val;
- currency = curr;
- testing::Notify();
- });
- testing::Wait();
-
- TEST_EQUAL(hotelId, kHotelId, ());
- TEST(!price.empty(), ());
- TEST(!currency.empty(), ());
- TEST_EQUAL(currency, "ISK", ());
- }
}
UNIT_CLASS_TEST(AsyncGuiThread, GetHotelInfo)
diff --git a/tools/python/ResponseProvider.py b/tools/python/ResponseProvider.py
index 550bd820ac..0b8eb176c8 100644
--- a/tools/python/ResponseProvider.py
+++ b/tools/python/ResponseProvider.py
@@ -141,10 +141,9 @@ class ResponseProvider:
"/id": self.my_id,
"/partners/time": self.partners_time,
"/partners/price": self.partners_price,
- "/booking/min_price": self.partners_minprice,
- "/booking/min_price.getHotelAvailability": self.partners_minprice,
- "/booking/min_price/hotelAvailability": self.partners_hotel_availability,
- "/booking/min_price/deals": self.partners_hotels_with_deals,
+ "/booking/hotelAvailability": self.partners_hotel_availability,
+ "/booking/deals": self.partners_hotels_with_deals,
+ "/booking/blockAvailability": self.partners_block_availability,
"/partners/taxi_info": self.partners_yandex_taxi_info,
"/partners/get-offers-in-bbox/": self.partners_rent_nearby,
"/partners/CalculateByCoords": self.partners_calculate_by_coords,
@@ -222,16 +221,15 @@ class ResponseProvider:
def partners_price(self):
return Payload(jsons.PARTNERS_PRICE)
-
- def partners_minprice(self):
- return Payload(jsons.PARTNERS_MINPRICE)
-
def partners_hotel_availability(self):
return Payload(jsons.HOTEL_AVAILABILITY)
def partners_hotels_with_deals(self):
return Payload(jsons.HOTELS_WITH_DEALS)
+ def partners_block_availability(self):
+ return Payload(jsons.BLOCK_AVAILABILITY)
+
def partners_yandex_taxi_info(self):
return Payload(jsons.PARTNERS_TAXI_INFO)
diff --git a/tools/python/jsons.py b/tools/python/jsons.py
index 68f512b37c..a8c0913b55 100644
--- a/tools/python/jsons.py
+++ b/tools/python/jsons.py
@@ -230,29 +230,67 @@ HOTELS_WITH_DEALS = """
}
"""
-PARTNERS_MINPRICE = """
-[
+BLOCK_AVAILABILITY = """
+{
+ "result": [
{
- "hotel_id":"0000000",
- "currency_code":"USD",
- "max_price":"5000.00",
- "ranking":1,
- "min_price":"250.00",
- "available_rooms":37,
- "other_currency": [
+ "direct_payment": true,
+ "checkin": "2018-06-16",
+ "hotel_id": 61394,
+ "block": [
+ {
+ "room_description": "Более просторные апартаменты-студио с кухней открытой планировки, телевизором с плоским экраном и бесплатным Wi-Fi.По запросу предоставляется DVD-плеер.",
+ "taxes": "НДС в размере 7 % , городской налог в размере 5 % ",
+ "rack_rate": {
+ "currency": "EUR",
+ "price": 0,
+ "other_currency": {
+ "currency": "RUB",
+ "price": 0
+ }
+ },
+ "block_id": "6139409_116589412_2_1_0",
+ "max_occupancy": 2,
+ "refundable": false,
+ "breakfast_included": true,
+ "is_smart_deal": false,
+ "incremental_price": [
{
- "currency_code":"RUB",
- "max_price":"250000.00",
- "min_price":"15000.00"
- },
+ "other_currency": {
+ "currency": "RUB",
+ "price": 8405.46
+ },
+ "price": 116,
+ "currency": "EUR"
+ }
+ ],
+ "photos": [
{
- "currency_code":"ISK",
- "max_price":"500000.00",
- "min_price":"30000.00"
+ "url_original": "https://q-xx.bstatic.com/images/hotel/max500/437/43793388.jpg",
+ "photo_id": 43793388,
+ "url_max300": "https://q-xx.bstatic.com/images/hotel/max300/437/43793388.jpg",
+ "url_square60": "https://q-xx.bstatic.com/images/hotel/square60/437/43793388.jpg"
}
- ]
+ ],
+ "deposit_required": false,
+ "name": "Синьо Студио 1 - Стоимость не возвращается",
+ "is_last_minute_deal": false,
+ "min_price": {
+ "other_currency": {
+ "currency": "RUB",
+ "price": 8405.46
+ },
+ "price": 116,
+ "currency": "EUR"
+ },
+ "refundable_until": "",
+ "room_id": 6139409
+ }
+ ],
+ "checkout": "2018-06-17"
}
-]
+ ]
+}
"""
PARTNERS_TAXI_INFO = """
diff --git a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj
index ec63df8e1a..733382a15d 100644
--- a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj
+++ b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj
@@ -42,6 +42,8 @@
3DA5713420B57358007BDE27 /* booking_params_base.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3DA5713320B57358007BDE27 /* booking_params_base.hpp */; };
3DBC1C541E4B14920016897F /* facebook_ads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DBC1C521E4B14920016897F /* facebook_ads.cpp */; };
3DBC1C551E4B14920016897F /* facebook_ads.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3DBC1C531E4B14920016897F /* facebook_ads.hpp */; };
+ 3DCD415320DAB33700143533 /* booking_block_params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DCD415120DAB33700143533 /* booking_block_params.cpp */; };
+ 3DCD415420DAB33700143533 /* booking_block_params.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3DCD415220DAB33700143533 /* booking_block_params.hpp */; };
3DF01C2D20652463005DDF8C /* taxi_places.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DF01C2A20652462005DDF8C /* taxi_places.cpp */; };
3DF01C2E20652463005DDF8C /* taxi_places.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3DF01C2B20652463005DDF8C /* taxi_places.hpp */; };
3DF9C219207CAC3000DA0793 /* taxi_places_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DF9C218207CAC3000DA0793 /* taxi_places_tests.cpp */; };
@@ -124,6 +126,8 @@
3DBC1C501E4B14810016897F /* facebook_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = facebook_tests.cpp; sourceTree = "<group>"; };
3DBC1C521E4B14920016897F /* facebook_ads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = facebook_ads.cpp; sourceTree = "<group>"; };
3DBC1C531E4B14920016897F /* facebook_ads.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = facebook_ads.hpp; sourceTree = "<group>"; };
+ 3DCD415120DAB33700143533 /* booking_block_params.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = booking_block_params.cpp; sourceTree = "<group>"; };
+ 3DCD415220DAB33700143533 /* booking_block_params.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = booking_block_params.hpp; sourceTree = "<group>"; };
3DF01C2A20652462005DDF8C /* taxi_places.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = taxi_places.cpp; sourceTree = "<group>"; };
3DF01C2B20652463005DDF8C /* taxi_places.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = taxi_places.hpp; sourceTree = "<group>"; };
3DF9C218207CAC3000DA0793 /* taxi_places_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = taxi_places_tests.cpp; sourceTree = "<group>"; };
@@ -227,6 +231,8 @@
F6B5363B1DA520B20067EEA5 /* partners_api */ = {
isa = PBXGroup;
children = (
+ 3DCD415120DAB33700143533 /* booking_block_params.cpp */,
+ 3DCD415220DAB33700143533 /* booking_block_params.hpp */,
346E888F1E9D087400D4CE9B /* ads_base.cpp */,
346E88901E9D087400D4CE9B /* ads_base.hpp */,
346E88911E9D087400D4CE9B /* ads_engine.cpp */,
@@ -341,6 +347,7 @@
3DA5713420B57358007BDE27 /* booking_params_base.hpp in Headers */,
346E88971E9D087400D4CE9B /* ads_base.hpp in Headers */,
3D7815761F3A14910068B6AC /* async_gui_thread.hpp in Headers */,
+ 3DCD415420DAB33700143533 /* booking_block_params.hpp in Headers */,
F67E75261DB8F06F00D6741F /* opentable_api.hpp in Headers */,
3D452AF41EE6D20D009EAB9B /* google_ads.hpp in Headers */,
F6B536411DA520E40067EEA5 /* booking_api.hpp in Headers */,
@@ -466,6 +473,7 @@
3DFEBF891EF82C1300317D5C /* viator_tests.cpp in Sources */,
3DFEBF851EF82BEA00317D5C /* viator_api.cpp in Sources */,
3D4E997D1FB439260025B48C /* booking_availability_params.cpp in Sources */,
+ 3DCD415320DAB33700143533 /* booking_block_params.cpp in Sources */,
F6B536421DA520E40067EEA5 /* uber_api.cpp in Sources */,
F6539537207FBED70057B97C /* taxi_places_loader.cpp in Sources */,
4566605020D91FEE0085E8C1 /* megafon_countries.cpp in Sources */,