Adding a specific price in the cart - prestashop

I would like to add a specific price for certain products in the cart. Currently I achieved that in one shop, but not in the other. I was able to add a specific price to a certain product (attribute) in the cart. I have this code that does the adding part:
foreach ($prices as $product) {
$specific_price = new SpecificPrice;
$specific_price->id_product = $product['id_product'];
$specific_price->id_product_attribute = $product['id_product_attribute'];
$specific_price->id_cart = (int)$params['cart']->id;
$specific_price->id_shop = $this->context->shop->id;
$specific_price->id_shop_group = $this->context->shop->id_shop_group;
$specific_price->id_country = $this->context->country->id;
$specific_price->id_currency = $this->context->currency->id;
$specific_price->id_group = $this->context->customer->id_default_group;
$specific_price->id_customer = $this->context->customer->id ? $this->context->customer->id : NULL;
$specific_price->from_quantity = 0;
$m2 = $product['m2'] < 0 ? 1 : round($product['m2']);
$specific_price->price = Tools::ps_round($product['price'] * $m2 / $product['quantity'], 6);
$specific_price->reduction_type = 'amount';
$specific_price->reduction_tax = 1;
$specific_price->reduction = 0;
$specific_price->from = date('Y-m-d H:i:s');
$specific_price->to = '0000-00-00 00:00:00';
try {
$specific_price->add(true);
} catch (Exception $e) {
Logger::addLog(sprintf('[%s] %s, line %d', $this->name, $e->getMessage(), __LINE__));
echo $e->getMessage();
if ($e->getCode() == 0) {
try {
$specific_price->update(true);
} catch (Exception $e) {
Logger::addLog(sprintf('[%s] %s, line %d', $this->name, $e->getMessage(), __LINE__ ));
echo $e->getMessage();
}
}
}
}
In id_shop 1 it works, but in the other shop id_shop 2 it doesn't. I'm cracking my head for hours on this. I've been clean cache everywhere possible, restart XAMPP, check http.conf for clues.
I have disabled id_customer as being required. Because I want to price to be saved for visitors/guests too.

Related

xero api failing to add tracking on purchase order

When I add tracking to invoices or credit notes via the api it works fine. but when i try to add it on purchase order it fails and I cannot seem to get a clear error message out of it.
I am using accounting api https://xeroapi.github.io/xero-php-oauth2/docs/v2/accounting/index.html#api-Accounting-updatePurchaseOrder
Error I get is message: "[400] Client error: POST https://api.xero.com/api.xro/2.0/PurchaseOrders/42797164-58c9-483c-9af8-96165c31a26f` resulted in a 400 Bad Request response:\n{\r\n "ErrorNumber": 10,\r\n "Type": "ValidationException",\r\n "Message": "A validation exception occurred",\r\n "Elements" (truncated...)\n"
`
Code I am using to try set it after I have created the purchase order.
[$trackingCategoryId, $trackingOptionId] = $this->getTrackingCategoryByNameFromXero($projectName, 'Project');
$purchaseOrder = null;
$xeroTenantId = $this->xero_account->tenantId;
try {
$purchaseOrders = $this->accountingApi->getPurchaseOrder($xeroTenantId, $purchaseOrderId);
foreach ($purchaseOrders as $model) {
if ($model->getPurchaseOrderId() == $purchaseOrderId) {
$purchaseOrder = $model;
break;
}
}
} catch (Exception $e) {
echo 'Exception when calling AccountingApi->getPurchaseOrder: ', $e->getMessage(), PHP_EOL;
}
if ($purchaseOrder instanceof PurchaseOrder) {
$lineItems = $purchaseOrder->getLineItems();
foreach ($lineItems as $lineItem) {
$tc = new LineItemTracking();
$tc->setTrackingCategoryId($trackingCategoryId);
$tc->setTrackingOptionId($trackingOptionId);
$lineItem->setTracking([$tc]);
$lineItems[] = $lineItem;
}
$purchaseOrder->setLineItems($lineItems);
$purchaseOrders = new PurchaseOrders();
$arr_purchase_orders[] = $purchaseOrder;
$purchaseOrders->setPurchaseOrders($arr_purchase_orders);
$summarizeErrors = true;
try {
$x = $this->accountingApi->updatePurchaseOrder(
$this->xero_account->tenantId,
$purchaseOrderId,
$purchaseOrders
);
} catch (\ApiException $e) {
print_r($e->getMessage());die;
}
}

How can I bind correctly my variables to my tokens?

I can't figure out what causes this error, I'm burned out already. I can't figure out how to solve this.
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter
number: number of bound variables does not match number of tokens in C:\wamp64\www\myproject-dev\public\viajes\orden_mantenimiento\controller.php on line 77
This happens when I try to execute my create method so heres the whole method:
if ($type == 'create') {
$Records = $request->models;
foreach ($Records as $rec) {
if (isset($request->pky)) {
$fky = $request->fky;
$rec->$fky = $request->pky;
}
$aError = Validate($rec);
$statement = $conn->prepare('INSERT INTO order (id, idVehiculo, idTipo, fecha, kilometraje, horaIn, horaSal, proyecto, jefeProy, aprobadoPor, descripcion)
VALUES (:id, :idVehiculo, idTipo, :fecha, :kilometraje, :horaIn, :horaSal, :proyecto, :jefeProy, :aprobadoPor, descripcion)');
$statement->bindValue(':id', $rec->id);
$statement->bindValue(':idVehiculo', $rec->idVehiculo);
$statement->bindValue(':idTipo', $rec->idTipo);
$statement->bindValue(':fecha', $rec->fecha);
$statement->bindValue(':kilometraje', $rec->kilometraje);
$statement->bindvalue(':horaIn', $rec->horaIn);
$statement->bindvalue(':horaSal', $rec->horaSal);
$statement->bindValue(':proyecto', $rec->proyecto);
$statement->bindValue(':jefeProy', $rec->jefeProy);
$statement->bindValue(':aprobadoPor', $rec->aprobadoPor);
$statement->bindValue(':descripcion', $rec->descripcion);
if (!$statement->execute()) { // **========================== THIS IS LINE 77 ===================**
$aErrInfo = $statement->errorInfo();
$aError = array();
$aError[] = array('success' => false);
$aError[] = array('msg' => $aErrInfo[1]);
$aError[] = array('error' => $aErrInfo[2]);
$respuesta["errors"] = $aError;
echo "statement error".$respuesta;
} else {
$rec->id = $conn->lastInsertId();
$respuesta["data"] = $rec;
echo "Data bound.";
}
} else {
$respuesta["errors"] = $aError;
echo "ERROR";
}
}
}
Thanks a lot in advance.

Segmentation fault in the below program

The below code is being called from a simple script like this.
$test.line-validation();
method line-validation is rw {
my $file-data = slurp($!FileName, enc => "iso-8859-1");
my #lines = $file-data.lines;
my $start = now;
for #lines -> $line {
state $i = 1;
my #splitLine = split('|', $line);
if ($line.starts-with("H|") || $line.starts-with("T|")) {
next;
}
my $lnObject = LineValidation.new( line => $line, FileType => $.FileType );
$lnObject.ColumnIds = %.ColumnIds;
my #promises;
my #validationIds;
for %.ValidationRules.keys -> $validationId {
if (%.ValidationRules{$validationId}<ValidationType> eq 'COLUMN') {
push #promises, start {$lnObject.ColumnValidationFunction(%.ValidationRules{$validationId}<ValidationFunction>, %.ValidationRules{$validationId}<Arguments>, $.ValidationRules{$validationId}<Description>); 1};
push #validationIds, $validationId;
}
}
my #promise-output = await #promises;
for #validationIds -> $valId {
state $j = 0;
my $result = #promise-output[$j];
if ($result.Bool == True) {
if (%.ResultSet{$valId}<count> :!exists) {
%.ResultSet{$valId}<count> = 1;
} else {
%.ResultSet{$valId}<count> = %.ResultSet{$valId}<count> + 1;
}
my #prCol = (%.ValidationRules{$valId}<Arguments><column>, #.printColumns);
if (%.ResultSet{$valId}<count> <= 10) {
%.ResultSet{$valId}.push: (sample => join('|', #splitLine[#prCol[*;*]].map: { if ($_.Bool == False ) { $_ = ''} else {$_ = $_;} }));
}
%.ResultSet{$valId}<ColumnList> = #prCol[*;*];
}
$j++;
}
$i++;
}
say "Line validation completed in {now - $start } time for $.lineCount lines";
}
The code was working fine earlier but when run using larger files, it just arbitrarily throws the error Segmentation fault and exists. I cannot determine where it is failing either.

get table rate shipping data in Woocommerce REST API

I am trying to get all active shipping methods in Woocommerce REST API. How can I achieve this. I am new to woocommerce REST API, Any help is much appreciated.
I want response something like this -
{
"shipping_methods": {
"method_id": "method_title"
}
}
I , finally, come up with the solution. It may help others.
Below is complete code to get all table rate shipping data including shipping zones, shipping methods by zone and rates by zone -
header('Content-type: application/json');
$json_file=file_get_contents('php://input');
$jsonvalue= json_decode($json_file,true);
global $wpdb;
global $woocommerce;
$active_methods = array();
$shipping_methods = $woocommerce->shipping->load_shipping_methods();
//echo "<pre>";print_r($shipping_methods);
foreach ( $shipping_methods as $id => $shipping_method ) {
if ( isset( $shipping_method->enabled ) && 'yes' === $shipping_method->enabled ) {
$data_arr = array( 'title' => $shipping_method->title, 'tax_status' => $shipping_method->tax_status );
if($id=='table_rate'){
$raw_zones = $wpdb->get_results("SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC;");
//echo "<pre>";print_r($raw_zones);
$shipping = array();
$shippingarr = array();
foreach ($raw_zones as $raw_zone) {
$zones = new WC_Shipping_Zone($raw_zone->zone_id);
$zone_id = $zones->zone_id;
$zone_name = $zones->zone_name;
$zone_enabled = $zones->zone_enabled;
$zone_type = $zones->zone_type;
$zone_order = $zones->zone_order;
$shipping['zone_id'] = $zone_id;
$shipping['zone_name'] = $zone_name;
$shipping['zone_enabled'] = $zone_enabled;
$shipping['zone_type'] = $zone_type;
$shipping['zone_order'] = $zone_order;
$shipping_methods = $zones->shipping_methods;
foreach($shipping_methods as $shipping_method){
$methodid = $shipping_method["number"];
$raw_rates[$methodid]['rates'] = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}woocommerce_shipping_table_rates WHERE shipping_method_id={$methodid};",ARRAY_A);
}
$shipping['shipping_methods'] = $raw_rates;
$raw_country = $wpdb->get_results("SELECT location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id={$zone_id};",ARRAY_N);
$shipping['countries'] = $raw_country;
$shippingarr[] = $shipping;
}
$data_arr['shipping_zones'] = $shippingarr;
}
$active_methods[ $id ] = $data_arr;
}
}
if(!empty($shippingarr)){
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']=$active_methods;
}else{
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']= array();
}
echo json_encode($result); `

Disable WooCommerce email notification for specific product

I can refer to this function to disable email notification:
https://docs.woocommerce.com/document/unhookremove-woocommerce-emails/
But I would like to disable it only for a specific product or, if it can be more simple, for a specific product category.
Thanks for your help
Thanks to #vidish-purohit for the help!
Here is my code to use if you need to disable admin email notification for a specific product:
function change_email_recipient_depending_of_product_id( $recipient, $order ) {
global $woocommerce;
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == xxx ) {
$recipient = '';
}
return $recipient;
}
}
add_filter( 'woocommerce_email_recipient_new_order', 'change_email_recipient_depending_of_product_id', 10, 2 );
And if you need to disable customer email notification for a specific product:
function change_email_recipient_depending_of_product_id( $recipient, $order ) {
global $woocommerce;
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == xxx ) {
$recipient = '';
}
return $recipient;
}
}
add_filter( 'woocommerce_email_recipient_customer_processing_order', 'change_email_recipient_depending_of_product_id', 10, 2 );
I think when you try to hook email notification from template, where you can find order, at that time emails are already sent.
You can try one thing - using recipient's hook you can remove recipient email and return empty string. Or if empty string triggers error, then you can give some dummy email.
Use this code for this:
// Change new order email recipient for registered customers
function wc_change_admin_new_order_email_recipient( $recipient, $order ) {
global $woocommerce;
// check if product in order
if ( true ) ) {
$recipient = "";
} else {
$recipient = "newbusiness#yourdomain.com";
}
return $recipient;
}
add_filter('woocommerce_email_recipient_new_order', 'wc_change_admin_new_order_email_recipient', 1, 2);
// Change new order email recipient for registered customers
function wc_change_admin_new_order_email_recipient( $recipient, $order ) {
$flagHasProduct = false;
// Get items in order
$items = $order->get_items();
// Loop for all items
foreach ( $items as $item ) {
$product_id = $item['product_id'];
// check if specific product is in order
if ( $product_id == 102 ) {
$flagHasProduct = true;
}
}
// if product is found then remove recipient
if ($flagHasProduct) {
$recipient = "";
} else {
$recipient = "newbusiness#yourdomain.com";
}
return $recipient;
}
add_filter('woocommerce_email_recipient_new_order', 'wc_change_admin_new_order_email_recipient', 1, 2);
The above code will disable the email option in the Woocommerce email setting option page.
/**
* Disable Admin email Notification for Specific Product
*/
function cstm_change_email_recipient_for_giftcard_product($recipient, $order)
{
// Bail on WC settings pages since the order object isn't yet set yet
// Not sure why this is even a thing, but shikata ga nai
$page = $_GET['page'] = isset($_GET['page']) ? $_GET['page'] : '';
if ('wc-settings' === $page) {
return $recipient;
}
// just in case
if (!$order instanceof WC_Order) {
return $recipient;
}
$items = $order->get_items();
foreach ($items as $item) {
$product_id = $item['product_id'];
if ($product_id == xxxx) {
$recipient = '';
}
return $recipient;
}
}
add_filter('woocommerce_email_recipient_new_order', 'cstm_change_email_recipient_for_giftcard_product', 10, 2);
this code works fine in latest version of Woocommerce.