feat: Add product price comparison table
- Add "Load Product Comparison" button in admin - Display WooCommerce products with local price (sale/regular) - Show Google Merchant Center price for each product - Show match type (offerId vs gtin) and match status - Helps debug product matching issues - Limited to 50 in-stock products for performance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -51,6 +51,7 @@ class Informatiq_SP_Admin {
|
||||
add_action( 'wp_ajax_informatiq_sp_manual_sync', array( $this, 'handle_manual_sync' ) );
|
||||
add_action( 'wp_ajax_informatiq_sp_test_connection', array( $this, 'handle_test_connection' ) );
|
||||
add_action( 'wp_ajax_informatiq_sp_revoke_auth', array( $this, 'handle_revoke_auth' ) );
|
||||
add_action( 'wp_ajax_informatiq_sp_compare_products', array( $this, 'handle_compare_products' ) );
|
||||
|
||||
// Enqueue admin assets.
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
||||
@@ -333,6 +334,10 @@ class Informatiq_SP_Admin {
|
||||
|
||||
<hr>
|
||||
|
||||
<?php $this->render_product_comparison(); ?>
|
||||
|
||||
<hr>
|
||||
|
||||
<?php $this->render_logs_section(); ?>
|
||||
</div>
|
||||
|
||||
@@ -575,6 +580,50 @@ class Informatiq_SP_Admin {
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render product comparison section.
|
||||
*/
|
||||
private function render_product_comparison() {
|
||||
?>
|
||||
<div class="informatiq-sp-product-comparison">
|
||||
<h2><?php esc_html_e( 'Product Price Comparison', 'informatiq-smart-pricing' ); ?></h2>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Compare WooCommerce product prices with Google Merchant Center prices.', 'informatiq-smart-pricing' ); ?>
|
||||
</p>
|
||||
|
||||
<?php if ( $this->is_authorized() ) : ?>
|
||||
<p>
|
||||
<button type="button" class="button button-secondary" id="informatiq-sp-compare-products">
|
||||
<?php esc_html_e( 'Load Product Comparison', 'informatiq-smart-pricing' ); ?>
|
||||
</button>
|
||||
<span class="spinner" style="float: none; margin-top: 0;"></span>
|
||||
</p>
|
||||
|
||||
<div id="informatiq-sp-comparison-results" style="display: none;">
|
||||
<table class="widefat striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Product', 'informatiq-smart-pricing' ); ?></th>
|
||||
<th><?php esc_html_e( 'SKU', 'informatiq-smart-pricing' ); ?></th>
|
||||
<th><?php esc_html_e( 'Local Price', 'informatiq-smart-pricing' ); ?></th>
|
||||
<th><?php esc_html_e( 'Google Price', 'informatiq-smart-pricing' ); ?></th>
|
||||
<th><?php esc_html_e( 'Google Match', 'informatiq-smart-pricing' ); ?></th>
|
||||
<th><?php esc_html_e( 'Status', 'informatiq-smart-pricing' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="informatiq-sp-comparison-tbody">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p class="description" style="color: #d63638;">
|
||||
<?php esc_html_e( 'Please authorize with Google first to compare products.', 'informatiq-smart-pricing' ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render logs section.
|
||||
*/
|
||||
@@ -752,6 +801,120 @@ class Informatiq_SP_Admin {
|
||||
wp_send_json_success( array( 'message' => __( 'Authorization revoked.', 'informatiq-smart-pricing' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle product comparison AJAX request.
|
||||
*/
|
||||
public function handle_compare_products() {
|
||||
check_ajax_referer( 'informatiq_sp_admin', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
||||
wp_send_json_error( array( 'message' => __( 'Insufficient permissions', 'informatiq-smart-pricing' ) ) );
|
||||
}
|
||||
|
||||
$merchant_id = get_option( 'informatiq_sp_merchant_id' );
|
||||
$client_id = get_option( 'informatiq_sp_client_id' );
|
||||
$client_secret = get_option( 'informatiq_sp_client_secret' );
|
||||
$refresh_token = get_option( 'informatiq_sp_refresh_token' );
|
||||
|
||||
if ( empty( $merchant_id ) || empty( $refresh_token ) ) {
|
||||
wp_send_json_error( array( 'message' => __( 'Please configure settings and authorize first.', 'informatiq-smart-pricing' ) ) );
|
||||
}
|
||||
|
||||
try {
|
||||
$google_api = new Informatiq_SP_Google_API(
|
||||
$merchant_id,
|
||||
$client_id,
|
||||
$client_secret,
|
||||
$refresh_token,
|
||||
$this->logger
|
||||
);
|
||||
|
||||
// Get all Google products indexed by various identifiers.
|
||||
$google_products_raw = $google_api->get_all_products();
|
||||
$google_products = array();
|
||||
|
||||
foreach ( $google_products_raw as $gp ) {
|
||||
// Index by offerId.
|
||||
if ( ! empty( $gp['offerId'] ) ) {
|
||||
$google_products['offer_' . $gp['offerId']] = $gp;
|
||||
}
|
||||
// Index by gtin.
|
||||
if ( ! empty( $gp['gtin'] ) ) {
|
||||
$google_products['gtin_' . $gp['gtin']] = $gp;
|
||||
}
|
||||
}
|
||||
|
||||
// Get WooCommerce in-stock products (limit to 50 for performance).
|
||||
$wc_products = wc_get_products( array(
|
||||
'status' => 'publish',
|
||||
'stock_status' => 'instock',
|
||||
'limit' => 50,
|
||||
'return' => 'objects',
|
||||
'type' => array( 'simple', 'variable' ),
|
||||
) );
|
||||
|
||||
$comparison = array();
|
||||
|
||||
foreach ( $wc_products as $product ) {
|
||||
$sku = $product->get_sku();
|
||||
if ( empty( $sku ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get local price (sale price priority, then regular).
|
||||
$sale_price = $product->get_sale_price();
|
||||
$regular_price = $product->get_regular_price();
|
||||
$local_price = ! empty( $sale_price ) ? $sale_price : $regular_price;
|
||||
$price_type = ! empty( $sale_price ) ? 'sale' : 'regular';
|
||||
|
||||
// Try to find matching Google product.
|
||||
$google_product = null;
|
||||
$match_type = '';
|
||||
|
||||
// Try offerId match.
|
||||
if ( isset( $google_products['offer_' . $sku] ) ) {
|
||||
$google_product = $google_products['offer_' . $sku];
|
||||
$match_type = 'offerId';
|
||||
}
|
||||
// Try GTIN match (when SKU is a barcode).
|
||||
elseif ( isset( $google_products['gtin_' . $sku] ) ) {
|
||||
$google_product = $google_products['gtin_' . $sku];
|
||||
$match_type = 'gtin';
|
||||
}
|
||||
|
||||
// Get Google price.
|
||||
$google_price = null;
|
||||
if ( $google_product ) {
|
||||
if ( isset( $google_product['price']['amountMicros'] ) ) {
|
||||
$google_price = (float) $google_product['price']['amountMicros'] / 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
$comparison[] = array(
|
||||
'id' => $product->get_id(),
|
||||
'name' => $product->get_name(),
|
||||
'sku' => $sku,
|
||||
'local_price' => $local_price ? (float) $local_price : null,
|
||||
'price_type' => $price_type,
|
||||
'google_price' => $google_price,
|
||||
'match_type' => $match_type,
|
||||
'found' => ! empty( $google_product ),
|
||||
'google_offer' => $google_product ? ( $google_product['offerId'] ?? '' ) : '',
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success( array(
|
||||
'products' => $comparison,
|
||||
'google_count' => count( $google_products_raw ),
|
||||
'wc_count' => count( $wc_products ),
|
||||
'currency' => get_woocommerce_currency_symbol(),
|
||||
) );
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
wp_send_json_error( array( 'message' => $e->getMessage() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin assets.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user