Issue on store credit of opencart 1.5.6 - php

I want to create an order for a customer in the administration. The customer has certain credit (let's say $200). The order total is calculated like order total - customer's credit = new order total.
The problem is the customer's credit does not change after creating an order.
For example:
the order total is: $500
credit is: $200
then the order total is : $500 - $200 = $300
but the customer's credit is still: $200
Has anybody else had the same problem?
I try to change the status of that order, both processing and setting, but it doesn't work.
The transaction in customer info page does not change.
I have checked the code in backend - there is no code that would operate with oc_customer_transaction table.
In frontend, there is a function in /catalog/model/total/credit.php
public function confirm($order_info, $order_total) {
$this->language->load('total/credit');
if ($order_info['customer_id']) {
$this->db->query("INSERT INTO " . DB_PREFIX . "customer_transaction SET
customer_id = '" . (int)$order_info['customer_id'] . "',
order_id = '" . (int)$order_info['order_id'] . "',
description = '" . $this->db->escape(
sprintf($this->language->get('text_order_id'),
(int)$order_info['order_id'])) . "',
amount = '" . (float)$order_total['value'] . "',
date_added = NOW()");
}
}
it is called during the checkout process to recalculate customer's credit balance. But I haven't found such code in backend.

I already fix that.
code:
$this->db->query("INSERT INTO " . DB_PREFIX . "customer_transaction SET
customer_id = '" . (int)$order_info['customer_id'] . "',
order_id = '" . (int)$order_info['order_id'] . "',
description = '" . $this->db->escape(
sprintf($this->language->get('text_order_id'),
(int)$order_info['order_id'])) . "',
amount = '" . (float)$order_total['value'] . "',
date_added = NOW()");
just add the credit calculate code when at following place:
1./admin/model/sale/order.php addOrder method
a. when you add product to a new customer order in the backend, the system will send request to the frontend (/catalog/checkout/mannual.php index ) wo calculate the order total(such as: subtotal, credit, shipping, total). after this request, order total in the page will be refreshed
b. when you save the order, the (admin/model/sale/order.php) addOrder method will be called eventually. You just need add code above to that function.
insert into..... customer_transaction means use the credit
2./admin/model/sale/order.php editOrder method
a. when you edit a order, the each item in totals will be changed. so, you should delete all credit you used for this order before.
delete * from oc_customer_transaction where 'order_id'=$order_id
b. since the each item of totals(involve credit) has been recalculated in step1, so this method will receive the new credit amount. just insert the new amount by code blow
3.you do not need to change admin/model/sale/order.php deleteOrder method
because it delete all totals, include item in the data table oc_customer_transaction
things done!

Related

How do I stop duplicate rows on table join in SQL?

Trying to join this table, so that i can change the code if the tutor ID matches the session tutor ID. But it shows multiple results in the calendar that its generating.
Below is the current PHP code, although the entries are being duplicated due to having multiple tutor ID's within the table. i'm not sure how to change this.
<?php
$sqlAssignments = "SELECT * FROM tbl_assignments LEFT JOIN tbl_tutorModules ON tbl_assignments.module_code = tbl_tutorModules.module_code"; //
$qryAssignments = mysqli_query($con, $sqlAssignments); // running the query
while($rowAssignment = mysqli_fetch_assoc($qryAssignments)){
if ($_SESSION["ID"] == $rowAssignment['tutor_id']) {
echo "{ title: '" . $rowAssignment['assignment_name'] . "', start: '" . $rowAssignment['hand_in_date'] . "', end: '" . $rowAssignment['hand_in_date'] . "', url: 'view/assignments.php?id=" . $rowAssignment['assignment_id'] . "', color: '#f1f1f1'},";
} else {
echo "{ title: '" . $rowAssignment['assignment_name'] . "', start: '" . $rowAssignment['hand_in_date'] . "', end: '" . $rowAssignment['hand_in_date'] . "', url: 'view/assignments.php?id=" . $rowAssignment['assignment_id'] . "'},";
}
}
?>
The actual results at the moment is that when the tutorModules has multiple tutors, the output duplicates calendar results.
Thanks
Edit: Tables look like this with some example data
tbl_tutorModules
con_id module_code tutor_id
2 ISYS30025 1
3 ISYS30025 2
tbl_assignments
assignment_id
module_code
assignment_name
assignment_weight
set_date
hand_in_date
hand_in_method
assignment_type
This is the current output
The expected output is for these not to be duplicated.
You want to know whether a certain tutor is involved in an assignment. So pass the tutor ID to the DBMS in order to let it find out in a query.
SELECT
assignment_id, assignment_name, hand_in_date,
case when module_code in (SELECT module_code FROM tbl_tutorModules WHERE tutor_id = ?)
then 'yes' else 'no'
end as tutor_involved
FROM tbl_assignments
ORDER BY assignment_id;
As you can see, I don't join the tables, because I'm not interested in the joined result. I merely want to look up a record in tbl_tutorModules. We use IN or EXISTS in SQL to look up records in another table.
See here how to pass parameters to the DBMS in mysqli: http://php.net/manual/en/mysqli.prepare.php

PHP MySQL Select a SUM minus a SUM

I'm trying to run a query like below:
SELECT (SUM(amount) - SUM(refundAmount)) as amount FROM orders WHERE $invoiceFilter AND $websiteFilter
It's getting the sum of the amount column correctly, but it's not subtracting out the refund amount.
What is the correct syntax for a query like this?
try this:
SELECT SUM(amount - refundAmount) AS `amount`
FROM orders
WHERE
invoice = $invoiceFilter
AND website = $websiteFilter;
You can use subqueries in the FROM clause.
SQL:
SELECT amount - refund
FROM (SELECT SUM(amount) as amount
FROM orders
WHERE invoice = 'invoiceFilter' AND website = 'websiteFilter') as a,
(SELECT SUM(refundAmount) as refund
FROM orders
WHERE invoice = 'invoiceFilter' AND website = 'websiteFilter') as b;
PHP:
mysql_query("SELECT amount - refund
FROM (SELECT SUM(amount) as amount
FROM orders
WHERE invoice = '" . mysql_real_escape_string($invoiceFilter). "'
AND website = '" . mysql_real_escape_string($websiteFilter). "') as a,
(SELECT SUM(refundAmount) as refund
FROM orders
WHERE invoice = '" . mysql_real_escape_string($invoiceFilter). "'
AND website = '" . mysql_real_escape_string($websiteFilter). "') as b; ");
You maybe missing something like a reference column to filter the data you need to process. Something like:
SELECT (SUM(amount) - SUM(refundAmount)) AS amount
FROM orders
WHERE
<a_column> = $invoiceFilter
AND <another_column> = $websiteFilter;

How do I get the lowest value from a MySQL (in PHP) row and obtain a name (or ID) that goes with it?

I have the follwing structure:
id,name,product,price
Now, I want to know how I can get the lowest value from price - and - get the name that belongs to the price. Here's a example:
0,seller1,cake,5
1,seller2,cake,2.50
Obviously seller2 has the lowest price. But I need to get that price - and the name that belongs to that price - and display it in PHP.
Something like this:
echo $seller . " sells " . $product . " for " . $price . ".";
I hope I have been clear enough.
Kind regards,
Hillebrand
The SQL to select what you need would be:
SELECT name, product, price FROM `table` ORDER BY price LIMIT 1
(Note that you didn't provide the table name so you'll need to replace table with the correct name.)
You can then use mysqli_stmt_fetch to fetch the results:
$stmt = $mysqli->prepare("SELECT name, product, price FROM `table` ORDER BY price LIMIT 1");
$stmt->execute();
$stmt->bind_result($seller, $product, $price);
$stmt->fetch();
echo $seller . ' sells ' . $product . ' for ' . $price . '.';
Keep in mind that this will only select the first product with the lowest price. You may need to consider how you'd like this to behave if you have two or more items which are equal in having the lowest price (e.g. 0). Should it display them all? Should there be some other field to signify precedence?
maybe
$table = mysql_query("SELECT name, price FROM table ORDER BY price ASC LIMIT 1");
while($y = mysql_fetch_object($table))
{
echo $y->name;
}

Custom price calculation in prestashop

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.

Opencart - Auto Disable "out of stock" Products

I'm looking for something more advanced than viewtopic.php?t=7080
I need to hide (or disable) products that are out of stock AND are in a specific category.
This problem arose because I have a category called "Clearance" and I want clearance items to automatically disable after selling out, as we'll never get more in stock. At the same time I want products in all other categories to continue to display after being out of stock.
Please help.
Mike
I would do this inside the confirm method of the order model. This is where quantities for products are updated once a sale is confirmed.
Open:
catalog/model/checkout/order.php
Within the confirm() method you'll find a line like:
foreach ($order_product_query->rows as $order_product) {
You could create a new method that would return the existing quantity for the given product, subtract the sold amount and check to see if the new quantity is 0, plus it would check if the product is attached to your given category.
If so, then set the product status to disabled if you don't want it to show at all, or set the stock_status to Out of Stock if you just want to show that it's sold out.
// check quantity and categories
private function checkQuantity ($product_id) {
$return = array();
// first check if product is attached to your specified category and add boolean to array
$categories = $this->db->query ("SELECT category_id FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
if (in_array($your_clearance_category_id, $categories->rows)):
$return['check'] = true;
else:
$return['check'] = false;
endif;
// get your pre-sale quantity and add to array
$quantity = $this->db->query ("SELECT quantity FROM " . DB_PREFIX . "product WHERE product_id = '" . (int)$product_id . "'");
$return['quantity'] = $quantity->row['quantity'];
return $return;
}
Then add this just after the opening of your foreach ($order_product_query->rows as $order_product) { structure:
$checks = $this->checkQuantity($order_product['product_id']);
if ($checks['check']):
if (((int)$check['quantity'] - (int)$order_product['quantity']) <= 0):
$this->db->query ("UPDATE " . DB_PREFIX . "product SET status = '0' WHERE product_id = '" . (int)$order_product['product_id'] . "'");
endif;
endif;
Haven't tested but it should work with or without a couple tweaks.

Categories