I create a custom feed for OpenCart.
I am trying to get a list of order details from OpenCart 1.54, however, I cannot find any JSON. Is there a way to return an error message, if the query fails?
Here is the URL to access:
/index.php?route=feed/api&func=getOrderProducts&orderid=1&email=xyz
My plugin files are here:
http://support.cloudcartconnector.com/hc/en-us/articles/202592798-OpenCart
On my test site, this works fine:
public function getOrderProducts($orderid) {
$query = $this->db->query("SELECT op.*, pr.sku, pr.quantity as stock FROM `" . DB_PREFIX . "order_product` op INNER JOIN `product` pr on op.product_id = pr.product_id WHERE op.order_id = '" . $this->db->escape($orderid) . "'");
return $query->rows;
}
I have no order prefix in my database. Here is the response:
[{"order_product_id":"1","order_id":"1","product_id":"43","name":"MacBook","model":"Product 16","quantity":"1","price":"500.0000","total":"500.0000","tax":"89.5000","reward":"600","sku":"macproduct1","stock":"927"}]
On several live sites, the code fails and I receive a blank white page. Here is the route itself:
// example function - getOrders from the database
private function getOrderProducts() {
if($this->request->get['email'] != "info#mysite.com")
{
return "INVALID EMAIL";
}
$this->load->model('feed/api');
return $this->model_feed_api->getOrderProducts($this->request->get['orderid']);
}
My code for getOrders work fine:
public function getOrders($beginDate, $endDate) {
$query = $this->db->query("select o.*, os.* from `" . DB_PREFIX . "order` o LEFT JOIN " . DB_PREFIX . "order_status os ON (o.order_status_id = os.order_status_id) where o.Date_Added >= $beginDate AND o.Date_Added <= $endDate");
return $query->rows;
}
The route for getOrderProducts actually works. If I put in a bad email, it returns INVALID EMAIL. Is there a way to return an exception message?
$this->request->get['orderid']
Maybe it's order_id (note underscore). It's a common name of the order ID value for OpenCart.
Change that code into
$this->request->get['order_id']
Related
The issue is Output on related products it shows on every related product box same total counted number in OpenCart. So, it see just main product_id. So, must indicate related product_id somehow. I tried many many ways but it don`t work for me. Can someone help me to fix this?
There is function on modules:
public function getUnitsSold($product_id) {
$query = $this->db->query("SELECT SUM(op.quantity) AS total FROM `" . DB_PREFIX . "order_product` op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id) WHERE o.order_status_id = '5' AND op.product_id = '" . (int)$product_id . "'");
if ($query->row) {
return $query->row['total'];
} else {
return FALSE;
}
}
And this is simply template output.
<?php if ($tproducts) { ?>
<?php foreach ($tproducts as $product) { ?>
<?php if ($product['units_sold']) { ?>
<?php echo $text_units_sold; ?> <?php echo $product['units_sold']; ?>
<?php } ?>
<?php } ?>
<?php } ?>
In controller where is related product array is a possibility to indicate maybe this function query and then make right output.
something like that units_sold?
$data['tproducts'][] = array(
'product_id' => $result['product_id'],
'units_sold' => $this->db->query("SELECT SUM(op.quantity) AS total FROM `" . DB_PREFIX . "order_product` op LEFT JOIN `" . DB_PREFIX . "order` o ON (op.order_id = o.order_id) WHERE o.order_status_id = '5' AND op.product_id = '" . (int)$product_id . "'"),
);
or maybe
$data['tproducts'][] = array(
'product_id' => $result['product_id'],
'units_sold' => $this->model_catalog_product->getUnitsSold($this->request->get['product_id']),
);
You'll want to store the amount of sold items on the item itself.
Increment the number as if it is a reverse stock.
So, I'd just ALTER TABLE oc_product ADD amount_sold INT(8) NULL DEFAULT NULL;
Then, just display that simple column value. The storage of the orders must be modified and becomes a little bit slower (in the order of .001 - .0001s).
This way the store will keep performing well in the future, even when your order item table has become huge.
Let the storage handler be the working horse. Take a look at ModelCheckoutOrder::addOrderHistory(), when they subtract the quantity, you must add your quantity :)
"UPDATE " . DB_PREFIX . "product SET /*.... opencart default shit */, amount_sold = (amount_sold + " . (int)$order_product['quantity'] . ")
I am trying to do one change in opencart source code (1.5.6 version), but unfortunately without success.
We have 5 languages on website with descriptions.
I want to show english description for the products on all version of languages on web site (on the page: ?route=product/product&product_id=X)
All other content will be on selected language but only description need be on english (no matter what language is selected).
I am searching for solution, and only logical for me is that this changes in code need to be make on product.php file under catalog/controller/product dir.
But can anybody give to me advice where to change the line of code where open cart select language id? In database english is language_id = 1
Maybe I can do this
remove this line on product.tpl
<div id="tab-description" class="tab-content"><?php echo $description; ?></div>
and put something like this, but how select description in this case
<div id="tab-description" class="tab-content"><?php SELECT DESCRIPTION FROM DATABASE WHERE LANGUAGE_ID =1 ?></div>
Mainly you need to modify your Model, Controller and View files:
Open you product model file from here : catalog/model/catalog/product.php
Add following code before line no 64 or public function getProducts($data = array()) {
public function getProductEngDesc($product_id) {
$query = $this->db->query("SELECT DISTINCT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '1' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
if ($query->num_rows) {
return array(
'description' => $query->row['description'],
);
} else {
return false;
}
}
Open you product Controller file from here : catalog/controller/product/product.php
Add following line after $product_info = $this->model_catalog_product->getProduct($product_id);
$product_eng_desc = $this->model_catalog_product->getProductEngDesc($product_id);
Add following line after $this->data['description'] = html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8');
$this->data['eng_description'] = html_entity_decode($product_eng_desc['description'], ENT_QUOTES, 'UTF-8');
Now open your Product template file and replace below line
<div id="tab-description" class="tab-content"><?php echo $description; ?></div>
With
<div id="tab-description" class="tab-content"><?php echo $eng_description; ?></div>
I'm working on a Prestashop 1.5.x website, where I need to add a custom price-calculation rule for a specific product.
My goal is to add 10 dollars per order, but PS adds extra cost by product quantity, so if you order 20 products it ask you 200$ instead of 10...
I need to override the calculating process in /classes/Product.php, with something like:
if (product_id = 44) { $price = $price + 10; }
else { $price = $price }
Have you got any idea?
You have to create an override of the Product class in prestashop. To do so, create a new file in override/classes called Product.php and put this code in it :
<?php
class Product extends ProductCore
{
// Here we will put every method or property override
}
In this class, you will copy / paste the static method priceCalculation (it's at line 2567 of original Product.php file for me). When done, just add these lines at the end of the method, just before the self::$_prices[$cache_id] = $price; :
if ($id_product == 44 && Context::getContext()->customer->isLogged()) {
$customer = Context::getContext()->customer;
$nbTimesBoughtThisProduct = (int) Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product` p
JOIN `' . _DB_PREFIX_ . 'order_detail` od
ON p.`id_product` = od.`product_id`
JOIN `' . _DB_PREFIX_ . 'orders` o
ON od.`id_order` = o.`id_order`
WHERE o.`id_customer` = ' . $customer->id . '
AND p.`id_product` = ' . $id_product . '
');
$price += $nbTimesBoughtThisProduct * 10;
}
I did not have the time to test these, but I think that's the way to do what you want to do.
priceCalculation is the method called each time Prestashop needs a product's price. By putting this code at the end of this method, we modify the returned price.
The code first checks if the customer is logged (we can't get orders from him if he is not). If so, a query retrieves the amount of times this customer bought this product in the past. This number is multiplied by ten, and the value is added to the price.
EDIT: If, as Cyril Tourist said, you want to also count the current cart, get this new code (still not tested, but should work) :
if ($id_product == 44 && Context::getContext()->customer->isLogged()) {
$customer = Context::getContext()->customer;
$nbTimesBoughtThisProduct = (int) Db::getInstance()->getValue('
SELECT COUNT(*)
FROM `' . _DB_PREFIX_ . 'product` p
JOIN `' . _DB_PREFIX_ . 'order_detail` od
ON p.`id_product` = od.`product_id`
JOIN `' . _DB_PREFIX_ . 'orders` o
ON od.`id_order` = o.`id_order`
WHERE o.`id_customer` = ' . $customer->id . '
AND p.`id_product` = ' . $id_product . '
');
$productsInCart = Context::getContext()->cart->getProducts();
foreach ($productsInCart as $productInCart) {
if ($productInCart['id_product'] == 44) {
$nbTimesBoughtThisProduct++;
}
}
$price += $nbTimesBoughtThisProduct * 10;
}
Also, I advice you to store the "44" product ID in a constant, configuration variable, or anything, but not keeping it in the code like that. I did that just for the example.
I have 2 tables:
competition_winners where I am storing people who won competition and table competition where I am storing info about actual competition.
So I am retrieving winners and competition's end date. But the query responsible for date doesn't return anything. I am using Opencart so performing query in model. Here is its code.
public function getWinnersByDate($date) {
$qr = "SELECT competition_id FROM " . DB_PREFIX . "competition_winners";
//$fcid = $qr->row['competition_id'];
$query = "SELECT cometition_id,end_date FROM " . DB_PREFIX . "competition WHERE competition_id = '" .$qr->row['competition_id'] . "'";
return $query->row;
Query works fine in PhpMyadmin. What am I missing or doing wrong?
Instead of running this in two queries You should be using JOIN (search about SQL JOIN on google).
public function getWinnersByDate($date) {
$qr = $this->db->query("
SELECT cw.competition_id, c.end_date
FROM " . DB_PREFIX . "competition_winners cw
LEFT JOIN " . DB_PREFIX . "competition c ON c.competition_id = cw.competition_id
");
return $query->rows;
}
I do not know Your DB structure, but the query above has no sense in it's current state - I believe You want to add some WHERE clause using the provided $date argument and that You want to select more information from competition_winners table, so please, either do it Yourself or provide us with more details on Your problem.
So I have 2 tables:
user_selection (id, user_id, fiche_id)
fiche (id, title, ...)
(fiche = sheet)
I have a research request which gives me some fiche ids
SELECT fiche.*, IF(fiche.fiche_type_id = 2,fiche.instance,fiche_type_texte.type_texte) AS type_texte, IF(fiche.fiche_type_id = 2,CONCAT(fiche.affaire," - ", fiche.titre),fiche.titre) AS titre, IF(fiche.fiche_type_id = 1,fiche.date_publication,fiche.date_texte) AS date_publication
FROM enviroveille_bascule.fiche
LEFT JOIN enviroveille_bascule.fiche_type_texte ON(fiche.fiche_type_texte_id = fiche_type_texte.id)
LEFT JOIN enviroveille_bascule.fiche_x_keyword ON(fiche_x_keyword.fiche_id = fiche.id)
LEFT JOIN enviroveille_bascule.fiche_x_theme ON(fiche_x_theme.fiche_id = fiche.id)
LEFT JOIN enviroveille_bascule.fiche_echeance ON(fiche_echeance.fiche_id = fiche.id)
LEFT JOIN enviroveille_bascule.fiche_x_activite ON(fiche_x_activite.fiche_id = fiche.id) LEFT JOIN enviroveille_bascule.fiche_x_nomenclature ON(fiche_x_nomenclature.fiche_id = fiche.id)
WHERE 1 = 1
AND fiche_echeance.fiche_echeance_type_id IN(2)
GROUP BY fiche.id
I'd like to know if all results from my research query is in the user selection.
So I tried :
// fiche_ids is an array of fiche.id resulting from research request
SELECT COUNT(*) AS nb
FROM " . $this->bdd . $this->table_user_selection . "
WHERE user_id = '" . $user->datas_user['id'] . "'
AND fiche_id IN ('" . implode("','", $fiche_ids) . "')
if($ds['nb'] == count($fiche_ids) && count($fiche_ids) > 0) {
return true;
} else {
return false;
}
That works well
Problem is that I have some research request giving 10K+ results.
And I have to do it several time on the same page, which makes server lags.
Is there a easy way to know if all my results are in my selection?
Note that selection may contain more fiche_id than the research result.
The best would be to be able do this in one SQL request.