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

View File

@@ -263,11 +263,14 @@ class Products
'cooldown_period' => \S::get( 'cooldown_period' ) '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( [ echo json_encode( [
'status' => 'ok', '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; exit;
} }

View File

@@ -280,14 +280,18 @@ class Products
], [ 'id' => $client_id ] ); ], [ '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; global $mdb;
$client_id = (int) $client_id; $client_id = (int) $client_id;
if ( $client_id <= 0 || !is_array( $settings ) ) 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'] ?? '' ) ); $entry_raw = trim( (string) ( $settings['bestseller_roas_entry'] ?? '' ) );
@@ -295,7 +299,11 @@ class Products
if ( !is_numeric( $entry_raw ) || !is_numeric( $exit_raw ) ) 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; $entry = (float) $entry_raw;
@@ -319,7 +327,11 @@ class Products
if ( empty( $rows ) ) if ( empty( $rows ) )
{ {
return 0; return [
'entry_count' => 0,
'cooldown_count' => 0,
'total_count' => 0
];
} }
$product_ids = []; $product_ids = [];
@@ -334,7 +346,11 @@ class Products
if ( empty( $product_ids ) ) if ( empty( $product_ids ) )
{ {
return 0; return [
'entry_count' => 0,
'cooldown_count' => 0,
'total_count' => 0
];
} }
$history_by_product = []; $history_by_product = [];
@@ -368,7 +384,9 @@ class Products
$history_by_product[ $pid ][] = (float) ( $history_row['roas'] ?? 0 ); $history_by_product[ $pid ][] = (float) ( $history_row['roas'] ?? 0 );
} }
$count = 0; $entry_count = 0;
$cooldown_count = 0;
$total_count = 0;
foreach ( $rows as $row ) foreach ( $rows as $row )
{ {
$product_id = (int) ( $row['id'] ?? 0 ); $product_id = (int) ( $row['id'] ?? 0 );
@@ -389,9 +407,11 @@ class Products
$entry_met = $roas_30 >= $entry && $conversions_30 >= $min_conversions; $entry_met = $roas_30 >= $entry && $conversions_30 >= $min_conversions;
$is_bestseller = false; $is_bestseller = false;
$is_kept_by_cooldown = false;
if ( $entry_met ) if ( $entry_met )
{ {
$entry_count++;
$is_bestseller = true; $is_bestseller = true;
} }
else if ( $current_label === 'bestseller' ) else if ( $current_label === 'bestseller' )
@@ -417,15 +437,31 @@ class Products
} }
$is_bestseller = !$below_exit_all_days; $is_bestseller = !$below_exit_all_days;
$is_kept_by_cooldown = $is_bestseller;
} }
if ( $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 ) 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.id AS product_id,
p.offer_id, p.offer_id,
p.min_roas, 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 CASE
WHEN COUNT( DISTINCT pa.campaign_id ) > 1 THEN \'--- wiele kampanii ---\' WHEN COUNT( DISTINCT pa.campaign_id ) > 1 THEN \'--- wiele kampanii ---\'
ELSE COALESCE( MAX( c.campaign_name ), \'--- brak kampanii ---\' ) ELSE COALESCE( MAX( c.campaign_name ), \'--- brak kampanii ---\' )
@@ -542,7 +581,7 @@ class Products
$params[':custom_label_4'] = '%' . $custom_label_4 . '%'; $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; $sql .= ' ORDER BY ' . $order_sql . ' ' . $order_dir . ', product_id DESC LIMIT ' . $start . ', ' . $limit;
return $mdb -> query( $sql, $params ) -> fetchAll( \PDO::FETCH_ASSOC ); return $mdb -> query( $sql, $params ) -> fetchAll( \PDO::FETCH_ASSOC );
@@ -626,7 +665,7 @@ class Products
$params = [ ':client_id' => (int) $client_id ]; $params = [ ':client_id' => (int) $client_id ];
$sql = 'SELECT COUNT(0) $sql = 'SELECT COUNT(0)
FROM ( FROM (
SELECT p.id, pa.campaign_id SELECT p.id
FROM products_aggregate AS pa FROM products_aggregate AS pa
INNER JOIN products AS p ON p.id = pa.product_id INNER JOIN products AS p ON p.id = pa.product_id
LEFT JOIN campaigns AS c ON c.id = pa.campaign_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 . '%'; $params[':custom_label_4'] = '%' . $custom_label_4 . '%';
} }
$sql .= ' GROUP BY p.id, pa.campaign_id $sql .= ' GROUP BY p.id
) AS grouped_rows'; ) AS grouped_rows';
return $mdb -> query( $sql, $params ) -> fetchColumn(); 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"> <button type="button" id="save_bestseller_rules" class="btn btn-primary btn-sm">
<i class="fa-solid fa-floppy-disk"></i> Zapisz <i class="fa-solid fa-floppy-disk"></i> Zapisz
</button> </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> </div>
</div> </div>
@@ -230,7 +230,7 @@ function reset_client_bestseller_settings_form()
$( '#bestseller_roas_exit' ).val( '' ); $( '#bestseller_roas_exit' ).val( '' );
$( '#min_conversions' ).val( '10' ); $( '#min_conversions' ).val( '10' );
$( '#cooldown_period' ).val( '14' ); $( '#cooldown_period' ).val( '14' );
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' ); $( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
} }
function preview_client_bestseller_settings() function preview_client_bestseller_settings()
@@ -239,11 +239,11 @@ function preview_client_bestseller_settings()
if ( !client_id || products_bestseller_settings_loading ) if ( !client_id || products_bestseller_settings_loading )
{ {
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' ); $( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
return; return;
} }
$( '#bestseller_rules_preview' ).text( 'Spelnia: licze...' ); $( '#bestseller_rules_preview' ).text( 'Wejscie: licze... | Cooldown: licze... | Lacznie: licze...' );
$.ajax({ $.ajax({
url: '/products/preview_client_bestseller_settings/', url: '/products/preview_client_bestseller_settings/',
@@ -259,14 +259,18 @@ function preview_client_bestseller_settings()
}).done( function( res ) { }).done( function( res ) {
if ( res && res.status === 'ok' ) 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 else
{ {
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' ); $( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
} }
}).fail( function() { }).fail( function() {
$( '#bestseller_rules_preview' ).text( 'Spelnia: -' ); $( '#bestseller_rules_preview' ).text( 'Wejscie: - | Cooldown: - | Lacznie: -' );
}); });
} }