Add functionality to manage and display minimum ROAS for bestsellers; implement AJAX calls for retrieval and saving

This commit is contained in:
2025-04-08 00:18:57 +02:00
parent ce9c9a1507
commit aeb7599811
5 changed files with 223 additions and 36 deletions

View File

@@ -13,7 +13,16 @@
"lmtime": 0,
"modified": false
},
"autoload": {},
"autoload": {
"controls": {
"class.Products.php": {
"type": "-",
"size": 7477,
"lmtime": 1741427168653,
"modified": false
}
}
},
"config.php": {
"type": "-",
"size": 357,
@@ -38,7 +47,32 @@
"lmtime": 0,
"modified": false
},
"layout": {},
"layout": {
"favicon.png": {
"type": "-",
"size": 353,
"lmtime": 0,
"modified": false
},
"style.css": {
"type": "-",
"size": 18247,
"lmtime": 1741427216637,
"modified": false
},
"style.css.map": {
"type": "-",
"size": 32918,
"lmtime": 1741427216637,
"modified": false
},
"style.scss": {
"type": "-",
"size": 22836,
"lmtime": 1741427216477,
"modified": false
}
},
"libraries": {},
"robots.txt": {
"type": "-",

View File

@@ -12,6 +12,8 @@ class Cron
exit;
}
$client_bestseller_min_roas = \factory\Products::get_client_bestseller_min_roas( $client_id );
$db_result = $mdb -> query( 'SELECT * FROM products AS p INNER JOIN products_history AS ph ON p.id = ph.product_id WHERE p.client_id = ' . $client_id ) -> fetchAll( \PDO::FETCH_ASSOC );
$aggregated_data = [];
@@ -61,46 +63,93 @@ class Cron
$cpc = $offer_data['clicks'] > 0 ? round( $offer_data['cost'] / $offer_data['clicks'], 6 ) : 0;
$roas = ($offer_data['conversions'] > 0 and $offer_data['cost']) ? round($offer_data['conversions_value'] / $offer_data['cost'], 2) * 100 : 0;
$impressions_30 = \factory\Products::get_impressions_30( $offer_data['product_id'] );
// $impressions_30 = \factory\Products::get_impressions_30( $offer_data['product_id'] );
if ( $impressions_30 <= 30 )
$custom_label_3 = 'product_zombie';
else
$custom_label_3 = null;
$offers_data_tmp = $mdb -> get( 'products_data', '*', [ 'product_id' => $offer_data['product_id'] ] );
if ( isset( $offers_data_tmp['id'] ) )
// update custom_label_4 only current is empty or is bestseller
$custom_label_4 = \factory\Products::get_product_data( $offer_data['product_id'], 'custom_label_4' );
if ( $custom_label_4 == null || $custom_label_4 == 'bestseller' )
{
if ( $custom_label_3 != $offers_data_tmp['custom_label_3'] )
$mdb -> insert( 'products_comments', [
'product_id' => $offer_data['product_id'],
'comment' => 'Zmiana pola "custom_label_3" na: ' . $custom_label_3,
'type' => 1,
'date_add' => date( 'Y-m-d' )
] );
$mdb -> update( 'products_data', [
'custom_label_3' => $custom_label_3
], [ 'id' => $offers_data_tmp['id'] ] );
}
else
{
$mdb -> insert( 'products_data', [
'product_id' => $offer_data['product_id'],
'custom_label_3' => $custom_label_3
] );
if ( $custom_label_3 == 'product_zombie' )
if ( $roas > $client_bestseller_min_roas and (int)$client_bestseller_min_roas > 0 and $offer_data['conversions'] > 10 )
{
$mdb -> insert( 'products_comments', [
$new_custom_label_4 = 'bestseller';
}
else
{
$new_custom_label_4 = null;
}
$offers_data_tmp = $mdb -> get( 'products_data', '*', [ 'product_id' => $offer_data['product_id'] ] );
if ( isset( $offers_data_tmp['id'] ) )
{
if ( $new_custom_label_4 != $offers_data_tmp['custom_label_4'] )
$mdb -> insert( 'products_comments', [
'product_id' => $offer_data['product_id'],
'comment' => 'Zmiana pola "custom_label_4" na: ' . $new_custom_label_4,
'type' => 1,
'date_add' => date( 'Y-m-d' )
] );
$mdb -> update( 'products_data', [
'custom_label_4' => $new_custom_label_4
], [ 'id' => $offers_data_tmp['id'] ] );
}
else
{
$mdb -> insert( 'products_data', [
'product_id' => $offer_data['product_id'],
'comment' => 'Zmiana pola "custom_label_3" na: product_zombie',
'type' => 1,
'date_add' => date( 'Y-m-d' )
'custom_label_4' => $new_custom_label_4
] );
if ( $new_custom_label_4 == 'bestseller' )
{
$mdb -> insert( 'products_comments', [
'product_id' => $offer_data['product_id'],
'comment' => 'Zmiana pola "custom_label_4" na: bestseller',
'type' => 1,
'date_add' => date( 'Y-m-d' )
] );
}
}
}
// if ( $impressions_30 <= 30 )
// $custom_label_3 = 'product_zombie';
// else
// $custom_label_3 = null;
// $offers_data_tmp = $mdb -> get( 'products_data', '*', [ 'product_id' => $offer_data['product_id'] ] );
// if ( isset( $offers_data_tmp['id'] ) )
// {
// if ( $custom_label_3 != $offers_data_tmp['custom_label_3'] )
// $mdb -> insert( 'products_comments', [
// 'product_id' => $offer_data['product_id'],
// 'comment' => 'Zmiana pola "custom_label_3" na: ' . $custom_label_3,
// 'type' => 1,
// 'date_add' => date( 'Y-m-d' )
// ] );
// $mdb -> update( 'products_data', [
// 'custom_label_3' => $custom_label_3
// ], [ 'id' => $offers_data_tmp['id'] ] );
// }
// else
// {
// $mdb -> insert( 'products_data', [
// 'product_id' => $offer_data['product_id'],
// 'custom_label_3' => $custom_label_3
// ] );
// if ( $custom_label_3 == 'product_zombie' )
// {
// $mdb -> insert( 'products_comments', [
// 'product_id' => $offer_data['product_id'],
// 'comment' => 'Zmiana pola "custom_label_3" na: product_zombie',
// 'type' => 1,
// 'date_add' => date( 'Y-m-d' )
// ] );
// }
// }
// Zapisujemy każdy zsumowany wpis do offers_temp
$clicks_30 = \factory\Products::get_clicks_30( $offer_data['product_id'] );

View File

@@ -2,6 +2,33 @@
namespace controls;
class Products
{
static public function get_client_bestseller_min_roas() {
$client_id = \S::get( 'client_id' );
$min_roas = \factory\Products::get_client_bestseller_min_roas( $client_id );
if ( $min_roas )
{
echo json_encode( [ 'status' => 'ok', 'min_roas' => $min_roas ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function save_client_bestseller_min_roas() {
$client_id = \S::get( 'client_id' );
$min_roas = \S::get( 'min_roas' );
if ( \factory\Products::save_client_bestseller_min_roas( $client_id, $min_roas ) )
{
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function main_view()
{
return \Tpl::view( 'products/main_view', [
@@ -41,6 +68,14 @@ class Products
if ( $custom_label_4 == 'product_deleted' )
$custom_class = 'text-danger';
$custom_label_4_color = '';
if ( $custom_label_4 == 'bestseller' )
$custom_label_4_color = 'background-color:rgb(96, 119, 102); color: #FFF;';
else if ( $custom_label_4 == 'deleted' )
$custom_label_4_color = 'background-color:rgb(255, 0, 0); color: #FFF;';
else if ( $custom_label_4 == 'zombie' )
$custom_label_4_color = 'background-color:rgb(58, 58, 58); color: #FFF;';
$data['data'][] = [
$row['product_id'],
$row['offer_id'],
@@ -54,7 +89,7 @@ class Products
</div>',
$row['impressions'],
$row['impressions_30'],
$row['clicks'],
'<span style="color: ' . ( $row['clicks'] > 100 ? '#57b951' : '' ) . '">' . $row['clicks'] . '</span>',
$row['clicks_30'],
round( $row['ctr'], 2 ) . '%',
\S::number_display( $row['cost'] ),
@@ -64,7 +99,7 @@ class Products
$row['roas'] <= $row['min_roas'] ? '<span class="text-danger text-bold">' . $row['roas'] . '</span>' : $row['roas'],
'<input type="text" class="form-control min_roas" product_id="' . $row['product_id'] . '" value="' . $row['min_roas'] . '" style="width: 100px;">',
'',
'<input type="text" class="form-control custom_label_4" product_id="' . $row['product_id'] . '" value="' . $custom_label_4 . '">'
'<input type="text" class="form-control custom_label_4" product_id="' . $row['product_id'] . '" value="' . $custom_label_4 . '" style="' . $custom_label_4_color . '">'
];
}

View File

@@ -2,6 +2,18 @@
namespace factory;
class Products
{
static public function get_client_bestseller_min_roas( $client_id )
{
global $mdb;
return $mdb -> get( 'clients', 'bestseller_min_roas', [ 'id' => $client_id ] );
}
static public function save_client_bestseller_min_roas( $client_id, $min_roas )
{
global $mdb;
return $mdb -> update( 'clients', [ 'bestseller_min_roas' => $min_roas ], [ 'id' => $client_id ] );
}
static public function save_min_roas( $product_id, $min_roas )
{
global $mdb;

View File

@@ -13,6 +13,12 @@
<i class="arrow double"></i>
</label>
</div>
<div class="col-md-1 text-right">
<label>Bestseller min ROAS</label>
</div>
<div class="col-md-3">
<input type="text" id="bestseller_min_roas" name="bestseller_min_roas" class="form-control" placeholder="Minimalny ROAS bestsellerów" value="" />
</div>
</div>
</div>
</div>
@@ -59,6 +65,29 @@
table = $( '#products' ).DataTable();
table.destroy();
// get min client roas
$.ajax({
url: '/products/get_client_bestseller_min_roas/',
type: 'POST',
data: {
client_id: client_id
},
success: function( response ) {
data = JSON.parse(response);
if ( data.status == 'ok' )
{
$( '#bestseller_min_roas' ).val( data.min_roas );
}
else
{
$( '#bestseller_min_roas' ).val( '' );
}
},
error: function() {
}
});
new DataTable( '#products', {
ajax: {
type: 'POST',
@@ -225,5 +254,33 @@
}
});
});
$( 'body' ).on( 'blur', '#bestseller_min_roas', function(){
var min_roas = $( this ).val();
var client_id = $( '#client_id' ).val();
$.ajax({
url: '/products/save_client_bestseller_min_roas/',
type: 'POST',
data: {
client_id: client_id,
min_roas: min_roas
},
success: function( response ) {
data = JSON.parse(response);
if ( data.status == 'ok' )
{
$.alert( 'Minimalny ROAS bestsellerów został pomyślnie zapisany' );
}
else
{
$.alert('Błąd: ' + response);
}
},
error: function() {
$.alert('Wystąpił błąd podczas zapisywania minimalnego ROAS. Spróbuj ponownie.');
}
});
});
});
</script>