Add competitor benchmark pricing and profit optimization

Features:
- Fetch competitor benchmark prices from Google Price Competitiveness Report
- New get_all_benchmark_prices() method in Google API class
- Display competitor price instead of own Google price
- Calculate recommended price (slightly below competitor)
- Show potential gain/loss per product if price is optimized
- Color-coded status:
  - Green: Your price is cheaper (opportunity to increase)
  - Blue: Competitive (within 2% of competitor)
  - Red: Expensive (above competitor)
- Summary statistics showing:
  - Products with benchmark data
  - Count by status (cheaper/competitive/expensive)
  - Total potential gain if all prices optimized

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-23 18:05:17 +01:00
parent 848a29dfa7
commit 4a34578e59
3 changed files with 235 additions and 51 deletions

View File

@@ -259,28 +259,82 @@ console.log('Informatiq Smart Pricing: Script loaded');
var data = response.data;
var html = '';
// Stats counters.
var stats = {
total: 0,
withBenchmark: 0,
cheaper: 0,
competitive: 0,
expensive: 0,
totalPotentialGain: 0
};
if (data.products.length === 0) {
html = '<tr><td colspan="6">No in-stock products with SKU found.</td></tr>';
} else {
$.each(data.products, function(i, product) {
var localPrice = product.local_price ? data.currency + parseFloat(product.local_price).toFixed(2) : '-';
var googlePrice = product.google_price ? data.currency + parseFloat(product.google_price).toFixed(2) : '-';
var priceLabel = product.price_type === 'sale' ? ' <small>(sale)</small>' : ' <small>(regular)</small>';
var matchLabel = product.match_type ? product.match_type : '-';
var statusClass = product.found ? 'color: #00a32a;' : 'color: #d63638;';
var statusText = product.found ? 'Found' : 'Not Found';
stats.total++;
if (product.found && product.google_offer) {
matchLabel += ' <small>(' + product.google_offer + ')</small>';
var localPrice = product.local_price ? data.currency + parseFloat(product.local_price).toFixed(2) : '-';
var benchmarkPrice = product.benchmark_price ? data.currency + parseFloat(product.benchmark_price).toFixed(2) : '-';
var recommendedPrice = product.recommended_price ? data.currency + parseFloat(product.recommended_price).toFixed(2) : '-';
var potentialGain = '-';
var priceLabel = product.price_type === 'sale' ? ' <small>(sale)</small>' : '';
// Status and colors.
var statusText = '-';
var statusStyle = '';
var localPriceStyle = '';
var gainStyle = '';
if (product.has_benchmark) {
stats.withBenchmark++;
if (product.price_status === 'cheaper') {
stats.cheaper++;
statusText = 'Cheaper';
statusStyle = 'color: #00a32a; font-weight: bold;';
localPriceStyle = 'color: #00a32a;';
} else if (product.price_status === 'competitive') {
stats.competitive++;
statusText = 'Competitive';
statusStyle = 'color: #2271b1; font-weight: bold;';
localPriceStyle = 'color: #2271b1;';
} else if (product.price_status === 'expensive') {
stats.expensive++;
statusText = 'Expensive';
statusStyle = 'color: #d63638; font-weight: bold;';
localPriceStyle = 'color: #d63638;';
}
if (product.potential_gain !== null) {
var gain = parseFloat(product.potential_gain);
stats.totalPotentialGain += gain;
if (gain > 0) {
potentialGain = '+' + data.currency + gain.toFixed(2);
gainStyle = 'color: #00a32a; font-weight: bold;';
} else if (gain < 0) {
potentialGain = '-' + data.currency + Math.abs(gain).toFixed(2);
gainStyle = 'color: #d63638;';
} else {
potentialGain = data.currency + '0.00';
}
}
} else if (product.found) {
statusText = 'No benchmark';
statusStyle = 'color: #dba617;';
} else {
statusText = 'Not in Google';
statusStyle = 'color: #888;';
}
html += '<tr>';
html += '<td><a href="post.php?post=' + product.id + '&action=edit">' + product.name + '</a></td>';
html += '<td><code>' + product.sku + '</code></td>';
html += '<td>' + localPrice + priceLabel + '</td>';
html += '<td>' + googlePrice + '</td>';
html += '<td>' + matchLabel + '</td>';
html += '<td style="' + statusClass + '"><strong>' + statusText + '</strong></td>';
html += '<td><a href="post.php?post=' + product.id + '&action=edit" title="SKU: ' + product.sku + '">' + product.name + '</a></td>';
html += '<td style="' + localPriceStyle + '">' + localPrice + priceLabel + '</td>';
html += '<td>' + benchmarkPrice + '</td>';
html += '<td>' + recommendedPrice + '</td>';
html += '<td style="' + gainStyle + '">' + potentialGain + '</td>';
html += '<td style="' + statusStyle + '">' + statusText + '</td>';
html += '</tr>';
});
}
@@ -288,10 +342,19 @@ console.log('Informatiq Smart Pricing: Script loaded');
$tbody.html(html);
$results.show();
// Show summary
var summary = 'Showing ' + data.products.length + ' WooCommerce products. ';
summary += data.google_count + ' products found in Google Merchant Center.';
$button.after('<p class="description" style="margin-top: 10px;">' + summary + '</p>');
// Show summary with statistics.
var $summary = $('#informatiq-sp-comparison-summary');
var summaryHtml = '<strong>Summary:</strong> ';
summaryHtml += stats.withBenchmark + ' of ' + stats.total + ' products have competitor data. ';
summaryHtml += '<span style="color:#00a32a;">' + stats.cheaper + ' cheaper</span>, ';
summaryHtml += '<span style="color:#2271b1;">' + stats.competitive + ' competitive</span>, ';
summaryHtml += '<span style="color:#d63638;">' + stats.expensive + ' expensive</span>. ';
if (stats.totalPotentialGain > 0) {
summaryHtml += '<br><strong style="color:#00a32a;">Total potential gain if optimized: +' + data.currency + stats.totalPotentialGain.toFixed(2) + ' per sale</strong>';
} else if (stats.totalPotentialGain < 0) {
summaryHtml += '<br><strong>Current margin vs recommended: ' + data.currency + stats.totalPotentialGain.toFixed(2) + '</strong>';
}
$summary.html(summaryHtml).show();
} else {
$status