Without using the Admin panel. I want to be able to change the price of an item in OpenCart on the product page.
Basically I have an Option called Bespoke/Custom:
which is a text field. If the customer enters anything here I want to be able to change the price which I do already via jQuery and then I want that new hidden field with the price to override the cart price for this customer order
Is that possible? Is there an extension where can I allow the customer to enter their own price then I could hide this field and update via jQuery etc
This is reference to some other posts Using an alternate price field in OpenCart and also about this model link http://forum.opencart.com/viewtopic.php?t=36052 which shows where the main oop functions are but it is quite extensive to do it their
OK, to point You the right direction this is how I would do this:
1. hidden input render
As You may know, in a catalog/view/theme/default/template/product/product.php
there is AJAX request for adding product into the cart:
$('#button-cart').bind('click', function() {
$.ajax({
url: 'index.php?route=checkout/cart/add',
type: 'post',
data: $('.product-info input[type=\'text\'], .product-info input[type=\'hidden\'], .product-info input[type=\'radio\']:checked, .product-info input[type=\'checkbox\']:checked, .product-info select, .product-info textarea'),
dataType: 'json',
// ...
});
});
If You look on the data
parameter You'll see that all the inputs, selects, textareas etc. present in a .product-info
div are populated and posted to PHP.
Therefore I'd render the hidden input with custom price value into that .product-info
div to not have to modify the AJAX request at all. Let's say the name of that input will be custom_price
.
2. The checkout/cart/add
Open up catalog/controller/checkout/cart.php
and search for add
method. Here all the magic should be done. After this part of code:
if (isset($this->request->post['option'])) {
$option = array_filter($this->request->post['option']);
} else {
$option = array();
}
I'd add this:
if(isset($this->request->post['custom_price']) && $this->isCustomPriceValid($this->request->post['custom_price'])) {
$custom_price = $this->request->post['custom_price'];
} else {
$custom_price = false;
}
Implement the isCustomPriceValid()
method to meet Your requirements...and advance to the last edit here - change this line:
$this->cart->add($this->request->post['product_id'], $quantity, $option);
to:
$this->cart->add($this->request->post['product_id'], $quantity, $option, $custom_price);
3. The cart
Now open up this file: system/library/cart.php
and again search for the add
method. You would have to change the definition of the method to this one:
public function add($product_id, $qty = 1, $option = array(), $custom_price = false) {
Before the last line of code within this method, add another one:
(this code was edited due to the comment from the OP)
// ...
if($custom_price) {
if(!isset($this->session->data['cart']['custom_price'])) {
$this->session->data['cart']['custom_price'] = array();
}
$this->session->data['cart']['custom_price'][$key] = $custom_price;
}
$this->data = array(); // <- last line
}
The last edit should be within the method getProducts()
as this one is loading all the data from the DB and forwards them to other controllers for displaying purposes.
Now I don't know whether Your custom price should overwrite the price + options price or only the price, thus options price will be added to it, so I'd stick with the second choice as it is more descriptive and the first choice could be easily derived from my example.
Search for the line
$price = $product_query->row['price'];
and right after add
if(isset($this->session->data['cart']['custom_price'][$key])) {
$price = $this->session->data['cart']['custom_price'][$key];
}
Now the price should be overwritten with the custom one. Check further that the price for the product is later set as:
$this->data[$key] = array(
// ...
'price' => ($price + $option_price),
// ...
);
So if You'd like to overwrite the whole price with the custom one, add that condition right after that array like this (instead of after $price = ...;
):
if(isset($this->session->data['cart']['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['cart']['custom_price'][$key];
}
This should be it. I didn't test the code, It may or may not work with slight modifications. I was working with OC 1.5.5.1. This should only point You to the right direction (while believing the finish is not that far).
Enjoy!
-"This should only point You to the right direction (while believing the finish is not that far). via @shadyyx"
Thank you @shadyyx - for showing the correct approach... I managed to get it working and this is how:
if(isset($this->session->data['cart']['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['cart']['custom_price'][$key];
}
should be :
if(isset($this->session->data['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['custom_price'][$key];
}
Thank you again and I hope somebody find this useful.