PrestaShop: Create new cart rule using custom code - php

I created a code to create new cart rule, it works great, but there's one issue, the restriction by product is not working...
Hoping someone can help, I tried looking the PrestaShop classes and controllers, and I tried to replicate, but this is what I got to and didn't work.
$coupon = new Discount();
$coupon->quantity = 1;
$coupon->quantity_per_user = 1;
$coupon->id_discount_type = 2;// reduction amount
$coupon->value = '10';
$coupon->id_customer = 1;
$coupon->minimum_amount = 0;
$coupon->minimum_amount_currency = 1;
$coupon->minimum_amount_tax = 0;
$coupon->minimum_amount_shipping = 0;
$coupon->quantity = 1;
$coupon->quantity_per_user = 1;
$coupon->product_restriction = 1;
$coupon->product_rule_group[] = 1;
$coupon->product_rule_group_1_quantity = 1;
$coupon->product_rule_1[] = 1;
$coupon->product_rule_1_1_type = 'products';
$coupon->product_rule_select_1_1[] = 9;
$coupon->reduction_percent = 100;
$coupon->reduction_amount = 0;
$coupon->reduction_currency = 1;
$coupon->reduction_tax = 0;
$coupon->apply_discount_to = 'specific';
$coupon->reductionProductFilter = '191072 Air Freshener Refill';
$coupon->reduction_product = 6;
$coupon->free_gift = 0;
$start_date = date('Y-m-d H:i:s');
$coupon->date_from = $start_date;
$end_date = date('Y-m-d H:i:s'); //some end date
$coupon->date_to = $end_date;
$gen_pass = strtoupper(Tools::passwdGen(8));
$vouchercode = 'somecode';
$name_v = $vouchercode.'-'.$gen_pass;
$namelang = array();
$namelang[1] = $name_v;
$namelang[2] = $name_v;;
//Add Name array
$coupon->name = $namelang;
$current_language = 1;
$coupon->id_customer = 1;
// fixed bug for currency
$coupon->reduction_currency = 1;
$coupon->minimum_amount_currency = 1;
$code_v = $vouchercode.'-'.$gen_pass;
$coupon->code = $code_v;
//$coupon->minimal = $coupon->value;
$coupon->active = 1;
//$coupon->cart_display = 1;
//$coupon->cart_rule_restriction = 0;
$coupon->description = '';
$coupon->highlight = 1;
$coupon->add();

We recommend you to use following code to create a cart rule.
Db::getInstance()->execute('INSERT INTO ' . _DB_PREFIX_ . 'cart_rule_shop
set id_cart_rule = ' . (int) $cart_rule_id . ', id_shop = ' . (int) $this->context->shop->id);
Db::getInstance()->execute('INSERT INTO ' . _DB_PREFIX_ . 'cart_rule_lang
set id_cart_rule = ' . (int) $cart_rule_id . ', id_lang = ' . (int) $this->context->language->id . ',
name = "' . strip_tags($coupon_name) . '"');
Db::getInstance()->execute('INSERT INTO ' . _DB_PREFIX_ . 'cart_rule_product_rule_group
set id_product_rule_group = NULL, id_cart_rule = ' . (int) $cart_rule_id . ',
quantity = 1');
$product_rule_group_id = Db::getInstance()->Insert_ID();
Db::getInstance()->execute('INSERT INTO ' . _DB_PREFIX_ . 'cart_rule_product_rule
set id_product_rule = NULL, id_product_rule_group = ' . (int) $product_rule_group_id . ',
type = "products"');
$product_rule_id = Db::getInstance()->Insert_ID();
Db::getInstance()->execute('INSERT INTO ' . _DB_PREFIX_ . 'cart_rule_product_rule_value
set id_product_rule =' . (int) $product_rule_id . ', id_item = ' . (int) $id_product . '');

i know it doesn't matter now but, anyways, if you're looking for a way to tie or add products to a specific cart rule, this might help
$products = [1 => "32232", 2 => "23232", 3 => "45343"];
So, after you $cartrule->add() you get, $cartRuleId = $cartrule->id
$coupon->product_restriction = 1; //enable product restriction
$coupon->reduction_product = -2; // write this only if you want the discount to be applied on the products in the cart and not the whole cart
(new Cart( $cart->id) )->addCartRule( (int) $cartRuleId); // apply the cart rule to this existing cart
# first, save `id_cart_rule` & `quantity` and get id_product_rule_group
Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_group` (`id_cart_rule`, `quantity`)
VALUES ('.(int)$cartRuleId.', "'.(int)$qty.'")');
$id_product_rule_group = Db::getInstance()->Insert_ID();
# second, save `id_product_rule_group` & `type` and get id_product_rule
Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule` (`id_product_rule_group`, `type`)
VALUES ('.(int)$id_product_rule_group.', "'.$type.'")');
$id_product_rule = Db::getInstance()->Insert_ID();
# finally, using id_product_rule assign products
foreach ($products as $id) {
$values[] = '('.(int)$id_product_rule.','.(int)$id.')';
}
$values = array_unique($values);
if (count($values)) {
Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_value` (`id_product_rule`, `id_item`) VALUES '.implode(',', $values));
}

If you don't want to engage in complex codes, this method may help you:
create Sample disabled coupon with your restrictions on admin panel
create object of your Sample coupon on your php file
clone object to newObject
change (code and active and etc) then add new coupon from it

Related

Improve CSV products import -> Array Category Query by name

recently we made a big change like build a new category tree for our website, and move over 2M products in the right category.
we have no performance issues, everything runs smoothly.
The only problem I have is that now the category tree is much more complex and deep, and it suffers when adding new articles via CSV import (timeout script, very slow, crash of script)
Basically a new product when it is added by CSV the category field is always textual (separated by "#") example: Engine#Crankshaft#Audi#Audi A5
So where is the problem is in my function for get the categoryID in case alredy exist in the database or not exist. How i can improve? i think the main problem is in the very big array created
protected function _getCategoriesID($field_value)
{
global $Database;
$products_categories = array();
$separator = $this->_getSeparator($field_value);
$category_array = array();
if ($separator != '') {
$category_array = explode($separator, $field_value);
$category_array = array_reverse($category_array);
} else {
$category_array[0] = $field_value;
}
unset($separator);
$Qcategory = $Database->query('select c0.categories_id from :table_categories as c0 inner join :table_categories_description as cd on c0.categories_id=cd.categories_id where cd.categories_name = :categories_name and cd.language_id=:language_id');
$Qcategory->bindTable(':table_categories', TABLE_CATEGORIES);
$Qcategory->bindTable(':table_categories_description', TABLE_CATEGORIES_DESCRIPTION);
$Qcategory->bindValue(':categories_name', $category_array[0]);
$Qcategory->bindInt(':language_id', $this->language);
$count = 1;
if (count($category_array) > 1) {
while ($count < count($category_array)) {
$Qcategory->appendQuery(' and c' . ($count - 1) . '.parent_id in (select c' . $count . '.categories_id from :table_categories' . $count . ' as c' . $count . ' inner join :table_categories_description' . $count . ' as cd' . $count . ' on c' . $count . '.categories_id=cd' . $count . '.categories_id where cd' . $count . '.categories_name = :categories_name' . $count . ' and cd' . $count . '.language_id=:language_id' . $count . ' ');
$Qcategory->bindTable(':table_categories' . $count, TABLE_CATEGORIES);
$Qcategory->bindTable(':table_categories_description' . $count, TABLE_CATEGORIES_DESCRIPTION);
$Qcategory->bindValue(':categories_name' . $count, $category_array[$count]);
$Qcategory->bindInt(':language_id' . $count, $this->language);
$count++;
}
for ($i = 0; $i < $count - 1; $i++) {
$Qcategory->appendQuery(')');
}
}
$Qcategory->execute();
while ($Qcategory->next()) {
$products_categories[] = $Qcategory->value('categories_id');
}
unset($Qcategories);
return $products_categories;
}

How give colour to a cell in pdf using php?

I need to give color to a specific cell in pdf which is generated from my MySQL database, How to set the color to the specific value?
I have no clue about giving color to the specific value, I there any way help me out?
my pdf generate page is:
$fdate = date('Y-m-d H:i:s', strtotime($fromdate));
$tdate = date('Y-m-d H:i:s', strtotime( $todate));
/*$channelsCol = Channels::find()
->select(['channel_name'])
->where('DeviceRefID != :id',['id' => 0 ])
->orderBy('channel_no')
->all();*/
$channelscol = \Yii::$app->db
->createCommand("select channel_name from channels where deviceRefID !=0")
->queryAll();
$pdfpages = $this->getNoOfPdfs(count($channelscol));
$noOfPages = count($pdfpages[0]);
$collist=[];
$selectlist=[];
for($i=0; $i < $noOfPages;$i++)
{
$collist[$i] = 'Select SQL_BUFFER_RESULT "LogDateTime ",';
$selectlist[$i] = 'select LogDateTime,';
}
$count =0;
$counter=1;
for($i=0;$i<$noOfPages;$i++)
{
for($j=$pdfpages[0][$i];$j<$pdfpages[1][$i];$j++)
{
$collist[$i] = $collist[$i] . '"'.$channelscol[$j-1]['channel_name'] .'",';
$selectlist[$i] = $selectlist[$i] . 'Channel'.$j.'Value,';
$count = $count + 1;
}
}
for($i=0;$i <$noOfPages ;$i++)
{
$collist[$i] = rtrim($collist[$i],",");
$selectlist[$i] = rtrim($selectlist[$i],",");
}
//$path ="/var/www/devicesadmin/yii-app/web/devicelog/devicelog" . date("Y-m-d-H-i-s").".csv";
$logfilename =[];
$logfailure="";
for($i=0;$i < $noOfPages; $i++)
{
$logfilename[$i] = $pdfpages[2][$i] . date("Y-m-d-H-i-s") . mt_rand() . ".csv";
//$path ='D:/Raffi/ProjectsPhp/DevicesAdminProject/yii-app/web/devicelog//' . $logfilename[$i];
$path = "/var/www/devicesadmin/yii-app/web/devicelog/" . $logfilename[$i];
$export =' INTO OUTFILE "' . $path . '" FIELDS TERMINATED BY "," ENCLOSED BY \'"\' LINES TERMINATED BY \'\\n\' FOR UPDATE';
$whereclause = "where LogDatetime between '" . $fdate . "' and '" .$tdate ."'";
$finalsql = $collist[$i] . ' Union all ' .$selectlist[$i] .' From devicelog '. $whereclause . $export;
try {
Yii::$app->db->createCommand($finalsql)->execute();
//file_put_contents("D:\my.txt", $this->getHTML($path, $header));
//echo html($this->getHTML($path, $header));
//exit();
$pdf=new \PDF('P','mm','Legal');
$pdf->AliasNbPages();
//$pdf=new \PDF('L','mm','Legal',130);
$pdf->AddPage();
$pdf->SetFont('helvetica','',10);
$pdf->WriteHTML($this->getHTML($path));
$logfilename[$i] = "dl" . $pdfpages[2][$i] . date("Y-m-d-H-i-s").".pdf";
//$filename = "D:/Raffi/ProjectsPhp/DevicesAdminProject\yii-app\web\devicelog" . $logfilename[$i];
$filename = "/var/www/devicesadmin/yii-app/web/devicelog/" . $logfilename[$i];
$pdf->Output('F',$filename);
unset($pdf);
} catch(Exception $e) {
}
}
If a pdf is generated, I need to give red color to the values which are above 50. But I can't get the values and give color.

PHP Oracle inserting data on loop got incorrect id

I'm continuing my previous question.
Now I need to insert the value to DB. But ID inserted is not correct as on my database master.
$qModel = oci_parse($c1, "SELECT MODELID, MODEL_NAME FROM WA_LFO_TBL_MODEL
WHERE ACTIVE = 'Y'");
oci_execute($qModel);
while($dModel = oci_fetch_array($qModel))
{
$qDtl2 = oci_parse($c1, "SELECT * FROM WA_LFO_TBL_MODEL_CONFIGURATION WHERE MODELID_FK = '" . $dModel['MODELID'] . "'");
oci_execute($qDtl2);
while($dDtl2 = oci_fetch_array($qDtl2))
{
$q = oci_parse($c1, "SELECT * FROM WA_LFO_TBL_REJECT_PROCESS WHERE MODELID_FK = '" . $dModel['MODELID'] . "' ORDER BY SORT_NO ASC");
oci_execute($q);
while($d = oci_fetch_array($q))
{
$idkeys[] = $d['RP_ID'];
$keys[] = $d['RP_NAME'];
}
$values = array_fill(0, count($keys), 0);
$values = array_combine($keys, $values);
for($i = $readRowAfter; $i < count($linesReject); $i++)
{
// if the fileReject is "Tue, Sep 18<tab>2018<tab>23:59:53<tab>"
$dateobjReject = DateTime::createFromFormat($createFromFormat, $linesReject[$i]);
// check if date is in your Timespan
if($dateobjReject < $toDateTime && $dateobjReject > $fromDateTime)
{
$rowsintimespanReject++; // count if in timespan
$lineContent = explode("\t", $linesReject[$i]);
// loop through line elements and count them
$x = 0;
for ($j = 0; $j < count($keys); $j++) {
if (!isset($lineContent[$j])) {
continue;
}
// remember position of last not empty column
if (trim($lineContent[$j]) != '') {
$x = $j;
}
}
if ($x > 0) {
$values[$keys[$x]]++;
}
}
}
$i = 0;
$sql = "";
foreach ($values as $value)
{
if($value != 0)
{
$sql = oci_parse($c1,"INSERT INTO WA_LFO_TBL_REJECT_OUTPUT(MODELID_FK, QUANTITY, RPID_FK, CONFIGURATIONID_FK)VALUES('" . $dModel['MODELID'] . "', '" . $value . "', '" . $idkeys[$i] . "', '" . $dDtl2['CONFIGURATIONID'] . "')");
oci_execute($sql);
}
$i++;
}
}
}
As you can see that I'm trying to insert the date on foreach function.
But inserted data for ID is not correct for RPID_FK.
I realize maybe something wrong with the code, tried to get the solution but still stuck on it.
Is something wrong on that code?

unset all elements of an array and resue it in php

i used unset method to empty my array it does but when i initilize same array again to reuse it in my code it gives the fatal error
Unsupported operand types
although other unset are working fine but only one array with integer type values have problem.
Any kind of help would be appreciated
here is my piece of code:
<?php
for ($citycount = 0; $citycount < $count; $citycount ++) {
$loc_qry = "SELECT `ID` as LocationID, `name` as LocationName FROM `territories` where `formatID` = 43 and `territorylevelID` = 77 and `parentID` = '" . $cityID_arr[$citycount] . "'";
$loc_qry_res = mysql_query($loc_qry) or die($loc_qry . "<br><br>" . mysql_error());
while ($rs_loc = mysql_fetch_array($loc_qry_res)) {
$location_id_arr[] = $rs_loc['LocationID'];
$location_name_arr [] = $rs_loc['LocationName'];
}
$count_loc = count($location_id_arr);
for ($i = 0; $i < $count_loc; $i++) {
$location_scores = "SELECT ((SUM(sa.achievedScore) / SUM(sa.totalScore)) * 100) as Score
FROM `scoreanalysis` as sa
WHERE `formatID` = 43 and `waveID` = '" . $wave_id_arr[0] . "' and `territoryID` = '" . $location_id_arr[$i] . "'";
$location_scores_res = mysql_query($location_scores);
while ($res_location_score = mysql_fetch_array($location_scores_res)) {
$location_scores_arr[] = intval($res_location_score['Score']);
}
if ($location_scores_arr[$i] != NULL) {
$divider = $divider + 1;
}
$cityscore = $cityscore + $location_scores_arr[$i];
//echo $location_id_arr[$i];
//echo $location_name_arr[$i]."<br>";
}
$total = $cityscore / $divider;
$city_qry = "SELECT `ID` as cityID, `name` as cityName FROM `territories` where `ID` = '" . $cityID_arr[$citycount] . "'";
$city_qry_rs = mysql_query($city_qry) or die($city_qry . "<br><br>" . mysql_error());
while ($city_name = mysql_fetch_array($city_qry_rs)) {
$cityname = $city_name['cityName'];
}
echo $cityname;
echo intval($total) . "%";
$total = 0;
$cityscore = 0;
unset($location_id_arr);
unset($location_name_arr);
$location_id_arr[] = array();
$location_name_arr[] = array();
unset($location_scores_arr);
$location_scores_arr[] = array();
$city_scores_arr [] = intval($total);
}
?>
The [] syntax is for adding an element to the end of an array; it's not valid for a variable you have just unset. Instead of trying to clear the array at the end of each iteration of the loop, you should be creating a new array at the beginning of each iteration, i.e.:
for ($citycount = 0; $citycount< $count; $citycount ++)
{
$location_id_arr = array();
$location_name_arr = array();
$location_scores_arr = array();
$loc_qry = "SELECT `ID` as LocationID, `name` as LocationName FROM `territories` where `formatID` = 43 and `territorylevelID` = 77 and `parentID` = '".$cityID_arr[$citycount]."'";
$loc_qry_res = mysql_query($loc_qry) or die($loc_qry."<br><br>".mysql_error());
...
}

Php and a dynamic loop for inserting into sql, both placement and variable must be dynamic

The vars are $ingval1 and so on.. the SQL fields are the same, obviously without the $..
This section of my script is not updating the table, why?
<?php // post
$basename1 = 'ingval';$basename2 = 'ingamt';
$basename3 = 'ingdes';$basename4 = 'ingcode';
for ($y = 1; $y < 26; $y++) {
$tempname1 = $basename1 . $y; $tempname2 = $basename2 . $y;
$tempname3 = $basename3 . $y; $tempname4 = $basename4 . $y;
$$tempname1 = $_POST['ingval'.$y];
$$tempname2 = $_POST['ingamt'.$y];
$$tempname3 = $_POST['ingdes'.$y];
$$tempname4 = $_POST['ingcode'.$y];
} // sql insert
$basename1 = 'ingval';$basename2 = 'ingamt';
$basename3 = 'ingdes';$basename4 = 'ingcode';
for ($y = 1; $y < 26; $y++) {
$tempname1 = $basename1 . $y; $tempname2 = $basename2 . $y;
$tempname3 = $basename3 . $y; $tempname4 = $basename4 . $y;
$sql = "UPDATE $cookbookdb SET
ingval.$y = '" . $$tempname1 . "',
ingamt.$y = '" . $$tempname2 . "',
ingdes.$y = '" . $$tempname3 . "',
ingcode.$y = '" . $$tempname4 . "'
WHERE id = '" . $barcodeinput . "'";
sql_query($sql)or die(mysql_error());
} ?>
I've tried this a few different ways and still no luck.
Why are you using variable variables in the update statement? It might be valid, but I cannot see any values from your code that would make it valid.
Should it be :
ingval.$y = '" . $tempname1 . "'
instead in your update statement?
From the code, the value of $tempname1 would be ingval1 through ingval26 but the value of $$tempname1 would be the value of the variable called $ingval1 through $ingval26 which I cannot see in the code at all.
are you sure you have connected to the database.
mysql_connect('host','username','password');
mysql_select_db('db');
if so what does the mysql_error() say?

Categories