Skip to content

Commit

Permalink
Merge pull request #2153 from woocommerce/tweak/budget-recommendations
Browse files Browse the repository at this point in the history
Tweak Budget recommendations logic
  • Loading branch information
puntope authored Nov 30, 2023
2 parents 9cc4551 + 7ef7f41 commit 2b9b5ae
Show file tree
Hide file tree
Showing 9 changed files with 4,368 additions and 4,289 deletions.
8,462 changes: 4,231 additions & 4,231 deletions data/budget-recommendations.csv

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ import './index.scss';
/*
* If a merchant selects more than one country, the budget recommendation
* takes the highest country out from the selected countries.
* When looking for the highest one, it should only consider the `daily_budget_high` value.
*
* For example, a merchant selected Brunei (5-20 USD) and Croatia (10-15 USD),
* then the budget recommendation should be (5-20 USD).
* For example, a merchant selected Brunei (20 USD) and Croatia (15 USD),
* then the budget recommendation should be (20 USD).
*/
function getHighestBudget( recommendations ) {
return recommendations.reduce( ( defender, challenger ) => {
if ( challenger.daily_budget_high > defender.daily_budget_high ) {
if ( challenger.daily_budget > defender.daily_budget ) {
return challenger;
}
return defender;
Expand All @@ -33,14 +32,14 @@ function getHighestBudget( recommendations ) {
function toRecommendationRange( isMultiple, ...values ) {
const conversionMap = { strong: <strong />, em: <em />, br: <br /> };
const template = isMultiple
? // translators: it's a range of recommended budget amount. 1: the low value of the range, 2: the high value of the range, 3: the currency of amount.
? // translators: it's a range of recommended budget amount. 1: the value of the budget, 2: the currency of amount.
__(
'Google will optimize your ads to maximize performance across the country/s you select.<br /><em>Tip: Most merchants targeting similar countries <strong>set a daily budget of %1$f to %2$f %3$s</strong></em>',
'Google will optimize your ads to maximize performance across the country/s you select.<br /><em>Tip: Most merchants targeting similar countries <strong>set a daily budget of %1$f %2$s</strong></em>',
'google-listings-and-ads'
)
: // translators: it's a range of recommended budget amount. 1: the low value of the range, 2: the high value of the range, 3: the currency of amount, 4: a country name selected by the merchant.
: // translators: it's a range of recommended budget amount. 1: the value of the budget, 2: the currency of amount 3: a country name selected by the merchant.
__(
'Google will optimize your ads to maximize performance across the country/s you select.<br /><em>Tip: Most merchants targeting <strong>%4$s set a daily budget of %1$f to %2$f %3$s</strong></em>',
'Google will optimize your ads to maximize performance across the country/s you select.<br /><em>Tip: Most merchants targeting <strong>%3$s set a daily budget of %1$f %2$s</strong></em>',
'google-listings-and-ads'
);

Expand All @@ -60,22 +59,18 @@ const BudgetRecommendation = ( props ) => {
}

const { currency, recommendations } = data;
const {
daily_budget_low: dailyBudgetLow,
daily_budget_high: dailyBudgetHigh,
country,
} = getHighestBudget( recommendations );
const { daily_budget: dailyBudget, country } =
getHighestBudget( recommendations );

const countryName = map[ country ];
const recommendationRange = toRecommendationRange(
recommendations.length > 1,
dailyBudgetLow,
dailyBudgetHigh,
dailyBudget,
currency,
countryName
);

const showLowerBudgetNotice = dailyAverageCost < dailyBudgetLow;
const showLowerBudgetNotice = dailyAverageCost < dailyBudget;

return (
<div className="gla-budget-recommendation">
Expand Down
15 changes: 5 additions & 10 deletions src/API/Site/Controllers/Ads/BudgetRecommendationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ protected function get_budget_recommendation_callback(): callable {
$returned_recommendations = array_map(
function ( $recommendation ) {
return [
'country' => $recommendation['country'],
'daily_budget_low' => (int) $recommendation['daily_budget_low'],
'daily_budget_high' => (int) $recommendation['daily_budget_high'],
'country' => $recommendation['country'],
'daily_budget' => (int) $recommendation['daily_budget'],
];
},
$recommendations
Expand Down Expand Up @@ -161,18 +160,14 @@ protected function get_schema_properties(): array {
'items' => [
'type' => 'object',
'properties' => [
'country' => [
'country' => [
'type' => 'string',
'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'google-listings-and-ads' ),
'context' => [ 'view' ],
],
'daily_budget_low' => [
'daily_budget' => [
'type' => 'number',
'description' => __( 'The lower bound recommended daily budget for a country.', 'google-listings-and-ads' ),
],
'daily_budget_high' => [
'type' => 'number',
'description' => __( 'The upper bound recommended daily budget for a country.', 'google-listings-and-ads' ),
'description' => __( 'The recommended daily budget for a country.', 'google-listings-and-ads' ),
],
],
],
Expand Down
64 changes: 64 additions & 0 deletions src/DB/Migration/Migration20231109T1653383133.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
declare( strict_types=1 );

namespace Automattic\WooCommerce\GoogleListingsAndAds\DB\Migration;

use Automattic\WooCommerce\GoogleListingsAndAds\DB\Table\BudgetRecommendationTable;

defined( 'ABSPATH' ) || exit;

Check warning on line 8 in src/DB/Migration/Migration20231109T1653383133.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Migration/Migration20231109T1653383133.php#L8

Added line #L8 was not covered by tests

/**
* Class Migration20231109T1653383133
*
* Migration class to reload the default Ads budgets recommendations provided by Google on 9 Nov 2023
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\DB\Migration
*
* @since x.x.x
*/
class Migration20231109T1653383133 extends AbstractMigration {

/**
* @var BudgetRecommendationTable
*/
protected $budget_rate_table;

/**
* Migration constructor.
*
* @param \wpdb $wpdb
* @param BudgetRecommendationTable $budget_rate_table
*/
public function __construct( \wpdb $wpdb, BudgetRecommendationTable $budget_rate_table ) {
parent::__construct( $wpdb );
$this->budget_rate_table = $budget_rate_table;

Check warning on line 34 in src/DB/Migration/Migration20231109T1653383133.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Migration/Migration20231109T1653383133.php#L32-L34

Added lines #L32 - L34 were not covered by tests
}


/**
* Returns the version to apply this migration for.
*
* @return string A version number. For example: 1.4.1
*/
public function get_applicable_version(): string {
return 'x.x.x';

Check warning on line 44 in src/DB/Migration/Migration20231109T1653383133.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Migration/Migration20231109T1653383133.php#L43-L44

Added lines #L43 - L44 were not covered by tests
}

/**
* Apply the migrations.
*
* @return void
*/
public function apply(): void {
if ( $this->budget_rate_table->exists() && $this->budget_rate_table->has_column( 'daily_budget_low' ) ) {
$this->wpdb->query( "ALTER TABLE `{$this->wpdb->_escape( $this->budget_rate_table->get_name() )}` DROP COLUMN `daily_budget_low`" ); // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared

Check warning on line 54 in src/DB/Migration/Migration20231109T1653383133.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Migration/Migration20231109T1653383133.php#L52-L54

Added lines #L52 - L54 were not covered by tests
}

if ( $this->budget_rate_table->exists() && $this->budget_rate_table->has_column( 'daily_budget_high' ) ) {
$this->wpdb->query( "ALTER TABLE `{$this->wpdb->_escape( $this->budget_rate_table->get_name() )}` DROP COLUMN `daily_budget_high`" ); // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared

Check warning on line 58 in src/DB/Migration/Migration20231109T1653383133.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Migration/Migration20231109T1653383133.php#L57-L58

Added lines #L57 - L58 were not covered by tests

}

$this->budget_rate_table->reload_data();

Check warning on line 62 in src/DB/Migration/Migration20231109T1653383133.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Migration/Migration20231109T1653383133.php#L62

Added line #L62 was not covered by tests
}
}
22 changes: 22 additions & 0 deletions src/DB/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,28 @@ protected function get_collation(): string {
return $this->wpdb->has_cap( 'collation' ) ? $this->wpdb->get_charset_collate() : '';
}

/**
* Checks whether a column exists for the table.
*
* @param string $column_name The column name.
*
* @return bool True if the column exists on the table or False if not.
*
* @since x.x.x
*/
public function has_column( string $column_name ): bool {

Check warning on line 139 in src/DB/Table.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Table.php#L139

Added line #L139 was not covered by tests
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$this->wpdb->get_results(
$this->wpdb->prepare( "SHOW COLUMNS FROM `{$this->get_sql_safe_name()}` WHERE Field = %s", [ $column_name ] )
);

Check warning on line 144 in src/DB/Table.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Table.php#L142-L144

Added lines #L142 - L144 were not covered by tests
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared

return (bool) $this->wpdb->num_rows;

Check warning on line 148 in src/DB/Table.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Table.php#L148

Added line #L148 was not covered by tests
}


/**
* Get the schema for the DB.
*
Expand Down
14 changes: 6 additions & 8 deletions src/DB/Table/BudgetRecommendationTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ protected function get_install_query(): string {
id bigint(20) NOT NULL AUTO_INCREMENT,
currency varchar(3) NOT NULL,
country varchar(2) NOT NULL,
daily_budget_low int(11) NOT NULL,
daily_budget_high int(11) NOT NULL,
daily_budget int(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY country_currency (country, currency)
) {$this->get_collation()};
Expand Down Expand Up @@ -86,11 +85,10 @@ public static function get_raw_name(): string {
*/
public function get_columns(): array {
return [
'id' => true,
'currency' => true,
'country' => true,
'daily_budget_low' => true,
'daily_budget_high' => true,
'id' => true,
'currency' => true,
'country' => true,
'daily_budget' => true,

Check warning on line 91 in src/DB/Table/BudgetRecommendationTable.php

View check run for this annotation

Codecov / codecov/patch

src/DB/Table/BudgetRecommendationTable.php#L88-L91

Added lines #L88 - L91 were not covered by tests
];
}

Expand Down Expand Up @@ -150,7 +148,7 @@ private function load_initial_data(): void {
* @param array $values
*/
private function insert_chunk( array $placeholders, array $values ): void {
$sql = "INSERT INTO `{$this->get_sql_safe_name()}` (currency,country,daily_budget_low,daily_budget_high) VALUES\n";
$sql = "INSERT INTO `{$this->get_sql_safe_name()}` (country,daily_budget,currency) VALUES\n";
$sql .= implode( ",\n", $placeholders );

// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
Expand Down
11 changes: 11 additions & 0 deletions src/DB/TableInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,15 @@ public function get_primary_column(): string;
* @since 1.4.1
*/
public function has_index( string $index_name ): bool;

/**
* Checks whether a column exists for the table.
*
* @param string $column_name The column name.
*
* @return bool True if the column exists on the table or False if not.
*
* @since x.x.x
*/
public function has_column( string $column_name ): bool;
}
2 changes: 2 additions & 0 deletions src/Internal/DependencyManagement/DBServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Automattic\WooCommerce\GoogleListingsAndAds\Internal\DependencyManagement;

use Automattic\WooCommerce\GoogleListingsAndAds\DB\Migration\Migration20231109T1653383133;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Migration\MigrationInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Migration\Migration20211228T1640692399;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Migration\Migration20220524T1653383133;
Expand Down Expand Up @@ -100,6 +101,7 @@ public function register() {
$this->share_migration( MigrationVersion141::class, MerchantIssueTable::class );
$this->share_migration( Migration20211228T1640692399::class, ShippingRateTable::class, OptionsInterface::class );
$this->share_with_tags( Migration20220524T1653383133::class, BudgetRecommendationTable::class );
$this->share_migration( Migration20231109T1653383133::class, BudgetRecommendationTable::class );

Check warning on line 104 in src/Internal/DependencyManagement/DBServiceProvider.php

View check run for this annotation

Codecov / codecov/patch

src/Internal/DependencyManagement/DBServiceProvider.php#L104

Added line #L104 was not covered by tests
$this->share_with_tags( Migrator::class, MigrationInterface::class );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,49 +53,41 @@ public function test_get_budget_recommendation() {

$budget_recommendation_data = [
[
'country' => 'US',
'daily_budget_low' => '330',
'daily_budget_high' => '930',
'country' => 'US',
'daily_budget' => '330',
],
[
'country' => 'GB',
'daily_budget_low' => '245',
'daily_budget_high' => '625',
'country' => 'GB',
'daily_budget' => '245',
],
[
'country' => 'TW',
'daily_budget_low' => '95',
'daily_budget_high' => '255',
'country' => 'TW',
'daily_budget' => '95',
],
[
'country' => 'JP',
'daily_budget_low' => '110',
'daily_budget_high' => '320',
'country' => 'JP',
'daily_budget' => '110',
],
];

$expected_response_data = [
'currency' => 'TWD',
'recommendations' => [
[
'country' => 'US',
'daily_budget_low' => 330,
'daily_budget_high' => 930,
'country' => 'US',
'daily_budget' => 330,
],
[
'country' => 'GB',
'daily_budget_low' => 245,
'daily_budget_high' => 625,
'country' => 'GB',
'daily_budget' => 245,
],
[
'country' => 'TW',
'daily_budget_low' => 95,
'daily_budget_high' => 255,
'country' => 'TW',
'daily_budget' => 95,
],
[
'country' => 'JP',
'daily_budget_low' => 110,
'daily_budget_high' => 320,
'country' => 'JP',
'daily_budget' => 110,
],
],
];
Expand Down

0 comments on commit 2b9b5ae

Please sign in to comment.