feat: Update client bestseller statistics handling and UI display

This commit is contained in:
2026-03-07 22:01:35 +01:00
parent 9bca12a59a
commit f39f216409
4 changed files with 78 additions and 32 deletions

View File

@@ -101,8 +101,8 @@
},
"class.Cron.php": {
"type": "-",
"size": 185030,
"lmtime": 1772117310268,
"size": 185177,
"lmtime": 1772899996837,
"modified": false
},
"class.FacebookAds.php": {
@@ -137,8 +137,8 @@
},
"class.Users.php": {
"type": "-",
"size": 21234,
"lmtime": 1772117354114,
"size": 21677,
"lmtime": 1772899952961,
"modified": false
},
"class.XmlFiles.php": {
@@ -289,9 +289,9 @@
},
"config.php": {
"type": "-",
"size": 921,
"lmtime": 1771497460705,
"modified": true
"size": 623,
"lmtime": 1772899939468,
"modified": false
},
"cron.php": {
"type": "-",
@@ -431,8 +431,8 @@
},
"index.php": {
"type": "-",
"size": 4599,
"lmtime": 1772382133382,
"size": 4702,
"lmtime": 1772899671144,
"modified": false
},
"install.php": {
@@ -826,8 +826,8 @@
},
"settings.php": {
"type": "-",
"size": 11754,
"lmtime": 1771198773079,
"size": 31507,
"lmtime": 1772899947661,
"modified": false
}
},

View File

@@ -263,11 +263,14 @@ class Products
'cooldown_period' => \S::get( 'cooldown_period' )
];
$count = \factory\Products::get_client_bestseller_preview_count( $client_id, $settings );
$stats = \factory\Products::get_client_bestseller_preview_stats( $client_id, $settings );
echo json_encode( [
'status' => 'ok',
'count' => (int) $count
'count' => (int) ( $stats['total_count'] ?? 0 ),
'entry_count' => (int) ( $stats['entry_count'] ?? 0 ),
'cooldown_count' => (int) ( $stats['cooldown_count'] ?? 0 ),
'total_count' => (int) ( $stats['total_count'] ?? 0 )
] );
exit;
}

View File

@@ -280,14 +280,18 @@ class Products
], [ 'id' => $client_id ] );
}
static public function get_client_bestseller_preview_count( $client_id, $settings )
static public function get_client_bestseller_preview_stats( $client_id, $settings )
{
global $mdb;
$client_id = (int) $client_id;
if ( $client_id <= 0 || !is_array( $settings ) )
{
return 0;
return [
'entry_count' => 0,
'cooldown_count' => 0,
'total_count' => 0
];
}
$entry_raw = trim( (string) ( $settings['bestseller_roas_entry'] ?? '' ) );
@@ -295,7 +299,11 @@ class Products
if ( !is_numeric( $entry_raw ) || !is_numeric( $exit_raw ) )
{
return 0;
return [
'entry_count' => 0,
'cooldown_count' => 0,
'total_count' => 0
];
}
$entry = (float) $entry_raw;
@@ -319,7 +327,11 @@ class Products
if ( empty( $rows ) )
{
return 0;
return [
'entry_count' => 0,
'cooldown_count' => 0,
'total_count' => 0
];
}
$product_ids = [];
@@ -334,7 +346,11 @@ class Products
if ( empty( $product_ids ) )
{
return 0;
return [
'entry_count' => 0,
'cooldown_count' => 0,
'total_count' => 0
];
}
$history_by_product = [];
@@ -368,7 +384,9 @@ class Products
$history_by_product[ $pid ][] = (float) ( $history_row['roas'] ?? 0 );
}
$count = 0;
$entry_count = 0;
$cooldown_count = 0;
$total_count = 0;
foreach ( $rows as $row )
{
$product_id = (int) ( $row['id'] ?? 0 );
@@ -389,9 +407,11 @@ class Products
$entry_met = $roas_30 >= $entry && $conversions_30 >= $min_conversions;
$is_bestseller = false;
$is_kept_by_cooldown = false;
if ( $entry_met )
{
$entry_count++;
$is_bestseller = true;
}
else if ( $current_label === 'bestseller' )
@@ -417,15 +437,31 @@ class Products
}
$is_bestseller = !$below_exit_all_days;
$is_kept_by_cooldown = $is_bestseller;
}
if ( $is_bestseller )
{
$count++;
$total_count++;
}
if ( $is_kept_by_cooldown )
{
$cooldown_count++;
}
}
return $count;
return [
'entry_count' => $entry_count,
'cooldown_count' => $cooldown_count,
'total_count' => $total_count
];
}
static public function get_client_bestseller_preview_count( $client_id, $settings )
{
$stats = self::get_client_bestseller_preview_stats( $client_id, $settings );
return (int) ( $stats['total_count'] ?? 0 );
}
static private function build_scope_filters( &$sql, &$params, $campaign_id, $ad_group_id )
@@ -481,7 +517,10 @@ class Products
p.id AS product_id,
p.offer_id,
p.min_roas,
pa.campaign_id,
CASE
WHEN COUNT( DISTINCT pa.campaign_id ) = 1 THEN MAX( pa.campaign_id )
ELSE 0
END AS campaign_id,
CASE
WHEN COUNT( DISTINCT pa.campaign_id ) > 1 THEN \'--- wiele kampanii ---\'
ELSE COALESCE( MAX( c.campaign_name ), \'--- brak kampanii ---\' )
@@ -542,7 +581,7 @@ class Products
$params[':custom_label_4'] = '%' . $custom_label_4 . '%';
}
$sql .= ' GROUP BY p.id, p.offer_id, p.min_roas, pa.campaign_id, p.name, p.title';
$sql .= ' GROUP BY p.id, p.offer_id, p.min_roas, p.name, p.title';
$sql .= ' ORDER BY ' . $order_sql . ' ' . $order_dir . ', product_id DESC LIMIT ' . $start . ', ' . $limit;
return $mdb -> query( $sql, $params ) -> fetchAll( \PDO::FETCH_ASSOC );
@@ -626,7 +665,7 @@ class Products
$params = [ ':client_id' => (int) $client_id ];
$sql = 'SELECT COUNT(0)
FROM (
SELECT p.id, pa.campaign_id
SELECT p.id
FROM products_aggregate AS pa
INNER JOIN products AS p ON p.id = pa.product_id
LEFT JOIN campaigns AS c ON c.id = pa.campaign_id
@@ -654,7 +693,7 @@ class Products
$params[':custom_label_4'] = '%' . $custom_label_4 . '%';
}
$sql .= ' GROUP BY p.id, pa.campaign_id
$sql .= ' GROUP BY p.id
) AS grouped_rows';
return $mdb -> query( $sql, $params ) -> fetchColumn();

View File

@@ -61,7 +61,7 @@
<button type="button" id="save_bestseller_rules" class="btn btn-primary btn-sm">
<i class="fa-solid fa-floppy-disk"></i> Zapisz
</button>
<span id="bestseller_rules_preview" style="margin-left:10px;color:#555;">Spelnia: -</span>
<span id="bestseller_rules_preview" style="margin-left:10px;color:#555;">Wejscie: - | Cooldown: - | Lacznie: -</span>
</div>
</div>
</div>
@@ -230,7 +230,7 @@ function reset_client_bestseller_settings_form()
$( '#bestseller_roas_exit' ).val( '' );
$( '#min_conversions' ).val( '10' );
$( '#cooldown_period' ).val( '14' );
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' );
$( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
}
function preview_client_bestseller_settings()
@@ -239,11 +239,11 @@ function preview_client_bestseller_settings()
if ( !client_id || products_bestseller_settings_loading )
{
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' );
$( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
return;
}
$( '#bestseller_rules_preview' ).text( 'Spelnia: licze...' );
$( '#bestseller_rules_preview' ).text( 'Wejscie: licze... | Cooldown: licze... | Lacznie: licze...' );
$.ajax({
url: '/products/preview_client_bestseller_settings/',
@@ -259,14 +259,18 @@ function preview_client_bestseller_settings()
}).done( function( res ) {
if ( res && res.status === 'ok' )
{
$( '#bestseller_rules_preview' ).text( 'Spelnia: ' + Number( res.count || 0 ) );
$( '#bestseller_rules_preview' ).text(
'Wejscie: ' + Number( res.entry_count || 0 ) +
' | Cooldown: ' + Number( res.cooldown_count || 0 ) +
' | Lacznie: ' + Number( res.total_count || res.count || 0 )
);
}
else
{
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' );
$( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
}
}).fail( function() {
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' );
$( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
});
}