1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/commerce/core/commerce_utils.h"
#include <string>
#include <vector>
#include "base/check.h"
#include "base/feature_list.h"
#include "base/json/json_writer.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/escape.h"
#include "base/time/time.h"
#include "base/uuid.h"
#include "base/values.h"
#include "components/commerce/core/commerce_constants.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/proto/price_tracking.pb.h"
#include "components/endpoint_fetcher/endpoint_fetcher.h"
#include "net/base/url_util.h"
#include "url/gurl.h"
namespace commerce {
GURL GetProductSpecsTabUrl(const std::vector<GURL>& urls) {
auto urls_list = base::Value::List();
for (auto& url : urls) {
urls_list.Append(url.spec());
}
std::string json;
if (!base::JSONWriter::Write(urls_list, &json)) {
return GURL(commerce::kChromeUICompareUrl);
}
return net::AppendQueryParameter(GURL(commerce::kChromeUICompareUrl), "urls",
json);
}
GURL GetProductSpecsTabUrlForID(const base::Uuid& uuid) {
return net::AppendQueryParameter(GURL(commerce::kChromeUICompareUrl), "id",
uuid.AsLowercaseString());
}
std::unique_ptr<ProductInfo> OptGuideResultToProductInfo(
const optimization_guide::OptimizationMetadata& metadata,
bool can_load_product_specs_full_page_ui) {
if (!metadata.any_metadata().has_value()) {
return nullptr;
}
std::optional<commerce::PriceTrackingData> parsed_any =
optimization_guide::ParsedAnyMetadata<commerce::PriceTrackingData>(
metadata.any_metadata().value());
commerce::PriceTrackingData price_data = parsed_any.value();
if (!parsed_any.has_value() || !price_data.IsInitialized()) {
return nullptr;
}
const commerce::BuyableProduct buyable_product = price_data.buyable_product();
std::unique_ptr<ProductInfo> info = std::make_unique<ProductInfo>();
if (buyable_product.has_title()) {
info->title = buyable_product.title();
}
if (buyable_product.has_gpc_title()) {
info->product_cluster_title = buyable_product.gpc_title();
}
if (buyable_product.has_image_url()) {
info->server_image_available = true;
info->image_url = GURL(buyable_product.image_url());
} else {
info->server_image_available = false;
}
if (buyable_product.has_offer_id()) {
info->offer_id = buyable_product.offer_id();
}
if (buyable_product.has_product_cluster_id()) {
info->product_cluster_id = buyable_product.product_cluster_id();
}
if (buyable_product.has_current_price()) {
info->currency_code = buyable_product.current_price().currency_code();
info->amount_micros = buyable_product.current_price().amount_micros();
}
if (buyable_product.has_country_code()) {
info->country_code = buyable_product.country_code();
}
// Check to see if there was a price drop associated with this product. Those
// prices take priority over what BuyableProduct has.
if (price_data.has_product_update()) {
const commerce::ProductPriceUpdate price_update =
price_data.product_update();
// Both new and old price should exist and have the same currency code.
bool currency_codes_match = price_update.new_price().currency_code() ==
price_update.old_price().currency_code();
if (price_update.has_new_price() &&
info->currency_code == price_update.new_price().currency_code() &&
currency_codes_match) {
info->amount_micros = price_update.new_price().amount_micros();
}
if (price_update.has_old_price() &&
info->currency_code == price_update.old_price().currency_code() &&
currency_codes_match) {
info->previous_amount_micros.emplace(
price_update.old_price().amount_micros());
}
}
if (buyable_product.has_category_data()) {
info->category_data = buyable_product.category_data();
}
// TODO(376128060): Remove the feature check after M132.
if (can_load_product_specs_full_page_ui) {
for (int i = 0; i < buyable_product.price_summary_size(); ++i) {
info->price_summary.push_back(buyable_product.price_summary(i));
}
if (buyable_product.has_price_display_recommendation()) {
info->price_display_recommendation =
buyable_product.price_display_recommendation();
}
}
return info;
}
void MaybeUseAlternateShoppingServer(
endpoint_fetcher::EndpointFetcher::RequestParams::Builder& params_builder) {
if (base::FeatureList::IsEnabled(commerce::kShoppingAlternateServer)) {
params_builder.SetHeaders(
std::vector<endpoint_fetcher::EndpointFetcher::RequestParams::Header>{
{kAlternateServerHeaderName, kAlternateServerHeaderTrueValue}});
}
}
} // namespace commerce
|