[iOS] add booking hot offers to PP

This commit is contained in:
Aleksey Belouosv 2018-08-06 18:13:26 +03:00 committed by Aleksey Belousov
parent ab686cb0ce
commit 582a0dd970
6 changed files with 168 additions and 93 deletions

View file

@ -150,7 +150,10 @@ using NewSectionsAreReady = void (^)(NSRange const & range, MWMPlacePageData * d
@property(copy, nonatomic) MWMVoidBlock refreshPreviewCallback;
@property(copy, nonatomic) place_page::NewSectionsAreReady sectionsAreReadyCallback;
@property(copy, nonatomic) MWMVoidBlock bannerIsReadyCallback;
@property(copy, nonatomic) MWMVoidBlock bookingDataUpdatedCallback;
@property(nonatomic, readonly) MWMUGCViewModel * ugc;
@property(nonatomic, readonly) NSInteger bookingDiscount;
@property(nonatomic, readonly) BOOL isSmartDeal;
// ready callback will be called from main queue.
- (instancetype)initWithPlacePageInfo:(place_page::Info const &)info;
@ -174,13 +177,12 @@ using NewSectionsAreReady = void (^)(NSRange const & range, MWMPlacePageData * d
// Booking
- (void)fillOnlineBookingSections;
- (MWMUGCRatingValueType *)bookingRating;
- (NSString *)bookingApproximatePricing;
- (NSString *)bookingPricing;
- (NSURL *)sponsoredURL;
- (NSURL *)deepLink;
- (NSURL *)sponsoredDescriptionURL;
- (NSURL *)bookingSearchURL;
- (NSString *)sponsoredId;
- (void)assignOnlinePriceToLabel:(UILabel *)label;
- (NSString *)hotelDescription;
- (vector<booking::HotelFacility> const &)facilities;
- (vector<booking::HotelReview> const &)hotelReviews;

View file

@ -38,6 +38,8 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
@property(copy, nonatomic) NSArray<MWMViatorItemModel *> * viatorItems;
@property(nonatomic) NSNumberFormatter * currencyFormatter;
@property(nonatomic, readwrite) MWMUGCViewModel * ugc;
@property(nonatomic) NSInteger bookingDiscount;
@property(nonatomic) BOOL isSmartDeal;
@end
@ -176,6 +178,51 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
});
}
- (void)requestBookingData
{
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
auto const api = GetFramework().GetBookingApi(canUseNetwork);
if (!api)
return;
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
auto const func = [self, currency](std::string const & hotelId,
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:[@(price.c_str())
stringByReplacingOccurrencesOfString:@"."
withString:decimalFormatter
.decimalSeparator]];
NSString * currencyString = [self.currencyFormatter stringFromNumber:currencyNumber];
dispatch_async(dispatch_get_main_queue(), ^{
self.cachedMinPrice = [NSString stringWithCoreFormat:L(@"place_page_starting_from")
arguments:@[currencyString]];
self.bookingDiscount = blocks.m_maxDiscount;
self.isSmartDeal = blocks.m_hasSmartDeal;
if (self.bookingDataUpdatedCallback)
self.bookingDataUpdatedCallback();
});
};
auto params = booking::BlockParams::MakeDefault();
params.m_hotelId = self.sponsoredId.UTF8String;
params.m_currency = currency;
api->GetBlockAvailability(std::move(params), func);
});
}
- (void)fillPreviewSection
{
if (self.title.length) m_previewRows.push_back(PreviewRows::Title);
@ -183,7 +230,10 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
if (self.subtitle.length || self.isMyPosition) m_previewRows.push_back(PreviewRows::Subtitle);
if (self.schedule != OpeningHours::Unknown) m_previewRows.push_back(PreviewRows::Schedule);
if (self.isBooking)
{
m_previewRows.push_back(PreviewRows::Review);
[self requestBookingData];
}
if (self.address.length) m_previewRows.push_back(PreviewRows::Address);
if (self.hotelType)
@ -522,7 +572,13 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
initWithValue:@(rating::GetRatingFormatted(ratingRaw).c_str())
type:[MWMPlacePageData ratingValueType:rating::GetImpress(ratingRaw)]];
}
- (NSString *)bookingApproximatePricing { return self.isBooking ? @(m_info.GetApproximatePricing().c_str()) : nil; }
- (NSString *)bookingPricing
{
ASSERT(self.isBooking, ("Only for booking.com hotels"));
return self.cachedMinPrice.length ? self.cachedMinPrice : @(m_info.GetApproximatePricing().c_str());
}
- (NSURL *)sponsoredURL
{
// There are sponsors without URL. For such psrtners we do not show special button.
@ -566,55 +622,6 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
: nil;
}
- (void)assignOnlinePriceToLabel:(UILabel *)label
{
NSAssert(self.isBooking, @"Online price must be assigned to booking object!");
if (self.cachedMinPrice.length)
{
label.text = self.cachedMinPrice;
return;
}
network_policy::CallPartnersApi([self, label](auto const & canUseNetwork) {
auto const api = GetFramework().GetBookingApi(canUseNetwork);
if (!api)
return;
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
auto const func = [self, label, currency](std::string const & hotelId,
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:[@(price.c_str())
stringByReplacingOccurrencesOfString:@"."
withString:decimalFormatter
.decimalSeparator]];
NSString * currencyString = [self.currencyFormatter stringFromNumber:currencyNumber];
self.cachedMinPrice = [NSString stringWithCoreFormat:L(@"place_page_starting_from")
arguments:@[currencyString]];
dispatch_async(dispatch_get_main_queue(), ^{
label.text = self.cachedMinPrice;
});
};
auto params = booking::BlockParams::MakeDefault();
params.m_hotelId = self.sponsoredId.UTF8String;
params.m_currency = currency;
api->GetBlockAvailability(std::move(params), func);
});
}
- (NSNumberFormatter *)currencyFormatter
{
if (!_currencyFormatter)

View file

@ -227,26 +227,27 @@ std::array<Class, 9> const kPreviewCells = {{[_MWMPPPTitle class],
[reviewCell configWithRating:data.bookingRating
canAddReview:NO
reviewsCount:0
priceSetter:^(UILabel * pricingLabel) {
pricingLabel.text = data.bookingApproximatePricing;
[data assignOnlinePriceToLabel:pricingLabel];
}
onAddReview:^{
}];
price:data.bookingPricing
discount:data.bookingDiscount
smartDeal:data.isSmartDeal
onAddReview:nil];
data.bookingDataUpdatedCallback = ^{
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
};
}
else
{
NSAssert(data.ugc, @"");
[reviewCell configWithRating:data.ugc.summaryRating
canAddReview:data.ugc.isUGCUpdateEmpty
reviewsCount:data.ugc.totalReviewsCount
priceSetter:^(UILabel * _Nonnull pricingLabel) {
pricingLabel.text = @"";
}
onAddReview:^{
[MWMPlacePageManagerHelper showUGCAddReview:MWMRatingSummaryViewValueTypeNoValue
fromPreview:YES];
}];
canAddReview:data.ugc.isUGCUpdateEmpty
reviewsCount:data.ugc.totalReviewsCount
price:@""
discount:0
smartDeal:NO
onAddReview:^{
[MWMPlacePageManagerHelper showUGCAddReview:MWMRatingSummaryViewValueTypeNoValue
fromPreview:YES];
}];
}
return reviewCell;
}

View file

@ -23,10 +23,35 @@ final class PPPReview: MWMTableViewCell {
}
}
private var onAddReview: (() -> Void)!
@IBOutlet private weak var discountView: UIView!
@IBOutlet private weak var discountLabel: UILabel!
@IBOutlet private weak var priceConstraint: NSLayoutConstraint!
@objc func config(rating: UGCRatingValueType, canAddReview: Bool, reviewsCount: UInt, priceSetter: (UILabel) -> Void, onAddReview: @escaping () -> Void) {
typealias OnAddReview = () -> ()
private var onAddReview: OnAddReview?
@objc func config(rating: UGCRatingValueType,
canAddReview: Bool,
reviewsCount: UInt,
price: String,
discount: Int,
smartDeal: Bool,
onAddReview: OnAddReview?) {
self.onAddReview = onAddReview
pricingLabel.text = price
if discount > 0 {
priceConstraint.priority = .defaultLow
discountView.isHidden = false
discountLabel.text = "-\(discount)%"
} else if smartDeal {
priceConstraint.priority = .defaultLow
discountView.isHidden = false
discountLabel.text = "%"
} else {
priceConstraint.priority = .defaultHigh
discountView.isHidden = true
}
ratingSummaryView.textFont = UIFont.bold12()
ratingSummaryView.value = rating.value
ratingSummaryView.type = rating.type
@ -49,7 +74,6 @@ final class PPPReview: MWMTableViewCell {
ratingSummaryView.noValueColor = UIColor.linkBlue()
reviewsLabel.text = L("placepage_reviewed")
pricingLabel.isHidden = false
priceSetter(pricingLabel)
}
} else {
ratingSummaryView.defaultConfig()
@ -62,12 +86,11 @@ final class PPPReview: MWMTableViewCell {
reviewsLabel.isHidden = true
}
pricingLabel.isHidden = false
priceSetter(pricingLabel)
}
}
@IBAction private func addReview() {
onAddReview()
onAddReview?()
}
override func layoutSubviews() {

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -18,8 +18,8 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="37.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="67u-jC-41D" customClass="RatingSummaryView" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="12" y="8" width="48" height="17.5"/>
<view contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="67u-jC-41D" customClass="RatingSummaryView" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="12" y="8" width="48" height="21.5"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" constant="48" placeholder="YES" id="Ebr-Th-1jm"/>
@ -50,14 +50,22 @@
<userDefinedRuntimeAttribute type="image" keyPath="badImage" value="ic_12px_rating_bad"/>
</userDefinedRuntimeAttributes>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="499" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsLetterSpacingToFitWidth="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XaG-Vf-CwT">
<rect key="frame" x="64" y="6.5" width="42" height="21"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalCompressionResistancePriority="499" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsLetterSpacingToFitWidth="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XaG-Vf-CwT">
<rect key="frame" x="64" y="8.5" width="118" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" verticalHuggingPriority="252" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ga0-6D-Ttl">
<rect key="frame" x="186" y="8" width="118" height="21"/>
<inset key="contentEdgeInsets" minX="8" minY="2" maxX="8" maxY="2"/>
<state key="normal" title="+ Leave review"/>
<connections>
<action selector="addReview" destination="ngD-jq-BYV" eventType="touchUpInside" id="P2B-73-A6f"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="$$$" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Thk-j3-Or0">
<rect key="frame" x="272" y="8.5" width="32" height="20.5"/>
<rect key="frame" x="272" y="8" width="32" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -67,7 +75,7 @@
</userDefinedRuntimeAttributes>
</label>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="separator_image" translatesAutoresizingMaskIntoConstraints="NO" id="t1Z-Sp-Xi5">
<rect key="frame" x="0.0" y="36.5" width="320" height="1"/>
<rect key="frame" x="0.0" y="36" width="320" height="1"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="LZA-3w-U5e"/>
</constraints>
@ -75,26 +83,51 @@
<userDefinedRuntimeAttribute type="string" keyPath="coloring" value="MWMSeparator"/>
</userDefinedRuntimeAttributes>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ga0-6D-Ttl">
<rect key="frame" x="190" y="8" width="118" height="17"/>
<inset key="contentEdgeInsets" minX="8" minY="2" maxX="8" maxY="2"/>
<state key="normal" title="+ Leave review"/>
<connections>
<action selector="addReview" destination="ngD-jq-BYV" eventType="touchUpInside" id="P2B-73-A6f"/>
</connections>
</button>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vIX-W5-Cye">
<rect key="frame" x="308" y="8" width="20" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="%" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aAP-XV-Kvr">
<rect key="frame" x="4" y="0.0" width="12" height="20"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium12"/>
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="white"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<color key="backgroundColor" red="0.11764705882352941" green="0.58823529411764708" blue="0.93983289930555558" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="aAP-XV-Kvr" firstAttribute="leading" secondItem="vIX-W5-Cye" secondAttribute="leading" constant="4" id="3Pt-fd-pmF"/>
<constraint firstItem="aAP-XV-Kvr" firstAttribute="top" secondItem="vIX-W5-Cye" secondAttribute="top" id="bQK-Uk-ysY"/>
<constraint firstAttribute="trailing" secondItem="aAP-XV-Kvr" secondAttribute="trailing" constant="4" id="efu-kY-HDe"/>
<constraint firstAttribute="bottom" secondItem="aAP-XV-Kvr" secondAttribute="bottom" id="kHg-Mm-xD9"/>
<constraint firstAttribute="height" constant="20" id="qsl-RB-coa"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="20" id="r42-aa-VVp"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="linkBlue"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<constraints>
<constraint firstItem="XaG-Vf-CwT" firstAttribute="centerY" secondItem="67u-jC-41D" secondAttribute="centerY" id="3GU-pM-RQN"/>
<constraint firstItem="t1Z-Sp-Xi5" firstAttribute="leading" secondItem="Zth-C7-aXm" secondAttribute="leading" id="5Qx-I3-eeG"/>
<constraint firstAttribute="trailing" secondItem="Ga0-6D-Ttl" secondAttribute="trailing" constant="12" id="6oV-WI-She"/>
<constraint firstAttribute="trailing" secondItem="vIX-W5-Cye" secondAttribute="trailing" priority="500" constant="16" id="5eo-tK-JDz"/>
<constraint firstItem="67u-jC-41D" firstAttribute="top" secondItem="Zth-C7-aXm" secondAttribute="top" constant="8" id="9Jf-DS-dPe"/>
<constraint firstItem="vIX-W5-Cye" firstAttribute="leading" secondItem="Thk-j3-Or0" secondAttribute="trailing" constant="4" id="9xP-tn-wsL"/>
<constraint firstItem="Ga0-6D-Ttl" firstAttribute="trailing" secondItem="Thk-j3-Or0" secondAttribute="trailing" id="AEw-hx-uNc"/>
<constraint firstAttribute="bottom" secondItem="t1Z-Sp-Xi5" secondAttribute="bottom" id="MXa-Ha-DVe"/>
<constraint firstItem="Thk-j3-Or0" firstAttribute="centerY" secondItem="Zth-C7-aXm" secondAttribute="centerY" id="NbS-0e-2Dh"/>
<constraint firstItem="Ga0-6D-Ttl" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="XaG-Vf-CwT" secondAttribute="trailing" constant="4" id="VnS-wf-vtj"/>
<constraint firstItem="Ga0-6D-Ttl" firstAttribute="leading" secondItem="XaG-Vf-CwT" secondAttribute="trailing" constant="4" id="VnS-wf-vtj"/>
<constraint firstAttribute="trailing" secondItem="t1Z-Sp-Xi5" secondAttribute="trailing" id="Ygd-7d-cGu"/>
<constraint firstAttribute="bottom" secondItem="67u-jC-41D" secondAttribute="bottom" constant="12" id="dOX-Tv-3un"/>
<constraint firstAttribute="trailing" secondItem="Thk-j3-Or0" secondAttribute="trailing" constant="16" id="dgG-Cd-fzs"/>
<constraint firstItem="vIX-W5-Cye" firstAttribute="centerY" secondItem="Zth-C7-aXm" secondAttribute="centerY" id="a4A-Q9-KmJ"/>
<constraint firstAttribute="bottom" secondItem="67u-jC-41D" secondAttribute="bottom" constant="8" id="dOX-Tv-3un"/>
<constraint firstAttribute="trailing" secondItem="Thk-j3-Or0" secondAttribute="trailing" priority="750" constant="16" id="dgG-Cd-fzs"/>
<constraint firstItem="Ga0-6D-Ttl" firstAttribute="top" secondItem="67u-jC-41D" secondAttribute="top" id="hGC-mM-qmJ"/>
<constraint firstItem="Ga0-6D-Ttl" firstAttribute="bottom" secondItem="67u-jC-41D" secondAttribute="bottom" id="j4s-Yj-bcx"/>
<constraint firstItem="XaG-Vf-CwT" firstAttribute="leading" secondItem="67u-jC-41D" secondAttribute="trailing" constant="4" id="mto-4q-X6o"/>
@ -104,6 +137,9 @@
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="addReviewButton" destination="Ga0-6D-Ttl" id="v9f-j8-mrO"/>
<outlet property="discountLabel" destination="aAP-XV-Kvr" id="268-Z8-9DU"/>
<outlet property="discountView" destination="vIX-W5-Cye" id="bw8-BM-fQL"/>
<outlet property="priceConstraint" destination="dgG-Cd-fzs" id="Ui6-TV-TfH"/>
<outlet property="pricingLabel" destination="Thk-j3-Or0" id="4Ai-fq-liR"/>
<outlet property="ratingSummaryView" destination="67u-jC-41D" id="4Zo-W4-dVh"/>
<outlet property="reviewsLabel" destination="XaG-Vf-CwT" id="h9W-nL-FiQ"/>

View file

@ -51,7 +51,7 @@ struct HotelInfo
struct Deals
{
enum Type
enum class Type
{
/// Good price.
Smart,
@ -88,6 +88,11 @@ struct Blocks
m_totalMinPrice = block.m_minPrice;
m_currency = block.m_currency;
}
if (!m_hasSmartDeal)
{
auto const & types = block.m_deals.m_types;
m_hasSmartDeal = std::find(types.cbegin(), types.cend(), Deals::Type::Smart) != types.cend();
}
if (block.m_deals.m_discount > m_maxDiscount)
m_maxDiscount = block.m_deals.m_discount;
@ -98,6 +103,7 @@ struct Blocks
std::string m_currency;
uint8_t m_maxDiscount = 0;
bool m_hasSmartDeal = false;
std::vector<BlockInfo> m_blocks;
};