Add a net price to products and show in orders

  • Posts: 6
  • Thank you received: 0
8 years 8 months ago #231911

-- HikaShop version -- : 2.6.1
-- Joomla version -- : 3.4.8
-- PHP version -- : 5.6.14
-- Browser(s) name and version -- : Chrome

Hi,
After looking for a while over forum I decided to leave my question over here.

I am working over a website which uses your spectacular Hikashop component ;-)
There is a request that I can't figure out by myself.

The client wants to have a net price value (not the retail price) in each product.
After this products are sold (state confirmed), in the order should have the total value of each net price product (admin side).

For example:
Product A : Price 100 ; Net 90
Product B : Price 120 ; Net 100
After sold, The total order is 220 and total net price is 190

I created a custom Text field "netvalue" for products table and another "netvaluetotal" for the order table.
So far so good.

As a developer, I think I need to create a plugin over the Order API.

Using onAfterOrderCreate, onAfterOrderUpdate and perhaps onAfterOrderDelete.

Now from, here I am a little stuck!!!
Can anyone give me so guidelines or another way to have this extra feature working.

Kind regards

Last edit: 8 years 8 months ago by solrac.

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
8 years 8 months ago #231920

Hi,

So you want to just implement onBeforeOrderCreate(&$order,&do), loop through the $order->cart->products list, get the product_id of each element and with it use this to load the netvalue of the product:
$productClass = hikashop_get('class.product');
$product = $productClass->get($product_id);
echo $product->netvalue;

Then, just sum them all into $order->netvaluetotal

The system will then save your value in the custom order field automatically.
And if you activated its display in the backend, you'll get to see it in the order details page of the backend automatically without doing anything else.

The following user(s) said Thank You: solrac

Please Log in or Create an account to join the conversation.

  • Posts: 6
  • Thank you received: 0
8 years 8 months ago #232025

Hi Nicolas,

Yes that's the main idea.
I did some tests and over look over the hikashop and my conclusion at first, was I need to create a extra column in the hikashop_order_product, to save this netvalue in each product in order (this column I need to insert via phpmyadmin).
So I have, netvalue on hikashop_product table, netvaluetotal in hikashop_order table and netvalue in the hikashop_order_product table

I did a plugin with triggers onAfterOrderCreate and onAfterOrderUpdate, you are talking to use onBeforeOrderCreate. Any reason in special?
Only after the update you know how many products you will have...

Over onAfterOrderCreate, I am getting all the $order->cart->products and sum each $product->netvalue, and I am storing it with a query!

The step I am now is over the onAfterOrderUpdate, because it not uses $order->cart and in some cases you can edit each product on the order,with the edit button at right.
So in the edition of each product on order I need to call the full order at the end and do the SUM again
$orderClass = hikashop_get('class.order');
$cOrder = $orderClass->loadFullOrder($order->order_id);

and then call my function to change the netvalue in hikashop_order_product for this product and sum all and store netvaluetotal from $cOrder

I think I am getting there. The most different thing on this plugin, is that I am using queries to save this values.
Any thoughts or better way to do this feature?

At the end of this work, I can have the netvaluetotal of all products in the order and perhaps also create another field to know the profit of the order ;-)

Thanks

Please Log in or Create an account to join the conversation.

  • Posts: 6
  • Thank you received: 0
8 years 8 months ago #232038

By the way, Nicolas...

I can open a new topic for this but..

Can you please create a simple plugin with function with this:
function onBeforeOrderUpdate(&$order,&$do)
{
$do = false;
return false;
}

And enable it!
Then go to one created order, edit a product on the action column(the pencil) and define another quantity and save it (the ajax request..).
The conclusion I got, is the event onBeforeOrderUpdate comes to much delayed.
The product on the order comes with this new quantity, even I deny it to do in the function onBeforeOrderUpdate and set $do = false;
Can you check the same steps also?

I installed the plugin hikashop_dump_events github.com/garstud/hikashop_dump_events
The events I can get before onBeforeOrderUpdate are onBeforeCalculateProductPriceForQuantityInOrder and onAfterCalculateProductPriceForQuantityInOrder

To help with the trace, the "path" for this ajax request is
controller order.php => function save
class order.php => function saveForm
goes until line "$currentTask = 'products';" does "$orderProductClass->update($product);" at end does "$this->recalculateFullPrice($order);" and finally the "$result = $this->save($order);"

So, is possible to deny this new quantity when stock don't have this quantity? :-D

This is because I am also making another plugin to check the quantity of product(stock) with the quantity in order.

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
8 years 8 months ago #232048

Hi,

1. You can also implement the onAfterOrderUpdate function for when the products are modified in the orders. But if you don't plan on manually modifying the orders, then it's not really necessary.

2. In onAfterOrderUpdate, you'll get the product that is being modified in $order->product or the products in $order->products when several are being modified at the same time. But when no product is modified (for example, when the status of the order is changed), you won't get the products in $order. But in that case, you probably don't want to do anything in your plugin.

3. Using queries is fine. It's easier when you're not familiar with the classes of HikaShop. But otherwise you can use the save functions of class.order or class.order_product.
For example:
$orderClass = hikashop_get('class.order');
$orderClass->save($cOrder);
The advantage is that your plugin will also trigger the other plugins and systems of HikaShop. But in your case, since you're only updating custom fields that aren't used by anything else, it's the same for you.

4.
The available quantity is actually not checked when you edit the order. You can do pretty much anything you want in HikaShop.
If you have a stock of 1 for a product, and you add it with a quantity of 5 in the order, you'll get a stock of 0 in the product but HikaShop will let you do it. You're the administrator, so you have the rights to override the rules. The check is really only enforced on the frontend with the cart system.

You're right about the onBeforeOrderUpdate. The trigger is called after the products have been modified because the modification of the products happens before the order is updated.
It would require either a trigger before any processing, or triggers to be added in the class.order_product.
I don't see how to do what you want with the triggers we have. The system wasn't made for that.
In that case, you would have to actually override the whole order class, extend it and redefine the saveForm function in it to add your check before calling the parent::saveForm.
Here is a thread about class overrides:
www.hikashop.com/forum/checkout/878018-c...asses-field-php.html

The following user(s) said Thank You: solrac

Please Log in or Create an account to join the conversation.

  • Posts: 6
  • Thank you received: 0
8 years 8 months ago #232166

Hi Nicolas,

First of all BIG thanks for your good explanation!

1. This website will need to have the possibility to change orders in a state order I defined as registered. But so far so good over here, as I also disable/hide the option to edit or delete a product when an order in afterword status like created,confirmed,shipped,etc...

2. In the functions of my plugin for onAfterOrderCreate(&$order,&$do) and onAfterOrderUpdate(&$order,&$do).
I defined some extra validations stages, like this for onAfterOrderCreate
if(isset($order->cart->products)) {
$products =& $order->cart->products;
} else {
$products =& $order->products;
}
$this->addNetValues($order,$products);
And in onAfterOrderUpdate
if(isset($order->products)) {
$products =& $order->products;
} else {
$products =& $order->product;
}
$this->addNetValues($order,$products);

Then in my function function addNetValues(&$order, &$products)
if(!empty($products)) {
.....

So I think is good this part, the change of status of order will not be executed inside my function addNetValues

3. One reason I used the query was also to avoid the triggers events called twice after the onAfterOrderUpdate with the use of $orderClass->save($cOrder), so I think is good as it is ;-)

4. This option is really to verify the quantity of product on the order and the stock available to avoid mistakes in admin side.
The order in NO case, must have more quantity than the stock available of the products.
That's why I am adding extra validations to the full store in admin side also.

I also created so far the order.override.html, was a little complicated to understand it! After all I need to have the file in front and also in admin html template!! But is done :-D
I have the extended functions save(..) and saveForm(..) on it, is more or less a copy from original with some changes I need to add.
The only thing I don't use in this cases was to call the parent::save but going directly to hikashopClass, again this is to avoid running twice the code and pass over my rules.
$parent = 'hikashopClass';
$parent::save($updateOrder);

So in conclusion and after your help and guidelines, seems I am just missing the quantity validation when I edit a product inside the order!
As I have already made the quantity validation plugin when a order changes.

Perhaps inside my order.overridehtml on saveForm($task = '') {
After line
$data = JRequest::getVar('data', array(), '', 'array');
I add this
$doit = true;
JPluginHelper::importPlugin('hikashop');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger('onBeforeSaveForm', array(&$order, $task, &$doit));
if($doit ) {
rest of the code lines
}

And in my plugin add function onBeforeSaveForm and do the validation starting from here.
So let's see how it will work and if passes right with my quantity validation.

I will lets you now.
And BIG THANKS again, because I also know what is giving support in the forum ;-)

Regards

Last edit: 8 years 8 months ago by solrac.

Please Log in or Create an account to join the conversation.

  • Posts: 6
  • Thank you received: 0
8 years 8 months ago #232174

I got it working :-D

In saveForm function in my override file I make this:

After
$data = JRequest::getVar('data', array(), '', 'array');
I added this:

$doit = true;
JPluginHelper::importPlugin('hikashop');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger('onBeforeSaveForm', array(&$order, $data, $task, &$doit));

if(!$doit) {
$app = JFactory::getApplication();
$app->close();
return;
}

Then in my plugin added:
function onBeforeSaveForm(&$order, $data, $task, &$doit)
{
if($task != 'products')
return true;

$cOrder = clone($order);
$cOrder->products = array(@$data);
return $this->onBeforeOrderUpdate($cOrder, $doit, false);// This last argument is to know if should use the usual order as in the others trigger
}

The ajax popup will stay on screen after save because of the close application and will report why it can be changed.
Now I need to debug and try several actions to see if all becomes correctly without interfering anything else..

Thanks, Nicolas

Please Log in or Create an account to join the conversation.

Time to create page: 0.075 seconds
Powered by Kunena Forum