TheBlackBenzKid TheBlackBenzKid - 1 month ago 13
jQuery Question

How can I change the original price on OpenCart product page?

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

Answer

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!