Add functionality to manage and display minimum ROAS for bestsellers; implement AJAX calls for retrieval and saving
This commit is contained in:
38
.vscode/ftp-kr.sync.cache.json
vendored
38
.vscode/ftp-kr.sync.cache.json
vendored
@@ -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": "-",
|
||||
|
||||
@@ -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'] );
|
||||
|
||||
|
||||
@@ -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 . '">'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user