Updating order's products' price with Mass Action button

  • Posts: 171
  • Thank you received: 9
1 year 10 months ago #342907

-- HikaShop version -- : 4.6.0
-- Joomla version -- : 4.1.5
-- PHP version -- : 7.4

Hi there!

We're using the Hikashop in a specialized way: user's do not see the prices, just afterwards their order is set to confirmed status.
Nowadays prices changing very fast, so it's really usual that we have to modify the prices on product's page - or with import/update.

(Edit) I've succesfully passed till button is shown, I can add status checkers there, but how can I refresh the order_product's values (price plus vat) and after that recalculate the whole order's price (I think I have to use run php and/or run mysql). Some help would be great in adding the correct code.

Also wanted to ask if I can add mass action button not just to listing but also to show order (backend) view?

If there's any other features that can help us in solving this (to not to manually set the products prices and then recalculate the whole order), any advice is welcomed.

Thanks in advance,
Regards,
PePe

Last edit: 1 year 10 months ago by pepecortez.

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

  • Posts: 81598
  • Thank you received: 13082
  • MODERATOR
1 year 10 months ago #342910

Hi,

Note that with HikaShop 4.6.0 we've added a "mass action as a button" feature. So you can configure actions in a massaction and make it as a button for the orders listing.
That way, on the orders listing, you can select orders you want to modify automatically, and you can click on that button and the actions of the mass action will run on these orders.
You can even use a PHP action in your mass action with PHP code if you need to check the status of the order, and do some complex update procedure on the order.

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

  • Posts: 171
  • Thank you received: 9
1 year 10 months ago #342923

nicolas wrote: Hi,

Note that with HikaShop 4.6.0 we've added a "mass action as a button" feature. So you can configure actions in a massaction and make it as a button for the orders listing.
That way, on the orders listing, you can select orders you want to modify automatically, and you can click on that button and the actions of the mass action will run on these orders.
You can even use a PHP action in your mass action with PHP code if you need to check the status of the order, and do some complex update procedure on the order.


Yeah, I've seen that, it's really awesome.

I'll solve somehow the price updating, but for the total order price recalculation I'd like to ask your help, as I'm sure that you have some top notch code lines in hand, how to easily do/trigger that.

Thanks in advance!

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

  • Posts: 81598
  • Thank you received: 13082
  • MODERATOR
1 year 10 months ago #342926

Hi,

In a PHP action, you can use such code:

$class = hikashop_get('class.order');
$order = $class->get({order_id});
$class->save($order);
The save function will call the recalculateFullPrice function of class.order to save the updated total amount.

The following user(s) said Thank You: pepecortez

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

  • Posts: 171
  • Thank you received: 9
1 year 10 months ago #342974

Thanks, that information is I was just looking for.
I added a Mass action but some small help would be great if there's no price for a variant (it uses it' parent's price).
Good to know that we use different prices for each user group.

Here's my code:

$application = JFactory::getApplication();
$class = hikashop_get('class.order');
$order = $class->loadFullOrder({order_id}, true, false);
$db = JFactory::getDbo();

if ($order->order_status == 'confirmed') {
$application->enqueueMessage(JText::_('Status is CONFIRMED, no price recalculation was made! '), 'error');
return;}

if ($order->order_status == 'shipped') {
$application->enqueueMessage(JText::_('Status is SHIPPED, no price recalculation was made! '), 'error');
return;}

if ($order->order_status == 'cancelled') {
$application->enqueueMessage(JText::_('Status is CANCELLED, no price recalculation was made! '), 'error');
return;}

if ($order->order_status == 'refunded') {
$application->enqueueMessage(JText::_('Status is REFUNDED, no price recalculation was made! '), 'error');
return;}


/* THAT PART IS NOT WORKING I DO NOT UNDERSTAND WHY - IT'S ONLY NEEDED IF WE CAN NOT CALIBRATE TO USE SQL UPDATE TO WORK WITH PARENT PRODUCT'S PRICE UNDERNEATH - START */
foreach($order->products as $product) {
if ($product->product_type == 'variant') {
$application->enqueueMessage('Order contains variant, no recalculation is made FOR VARIANT!', 'error');}
}
/* END */


$sql = "UPDATE #__hikashop_order_product as op
LEFT JOIN #__hikashop_product as p ON op.product_id = p.product_id
LEFT JOIN #__hikashop_order as o ON op.order_id = ".$order->order_id."
LEFT JOIN #__hikashop_user as u ON o.order_user_id = u.user_id
LEFT JOIN #__user_usergroup_map as ug ON u.user_cms_id = ug.user_id
LEFT JOIN #__hikashop_price as pr ON op.product_id = pr.price_product_id
SET op.order_product_price = pr.price_value, op.order_product_tax = pr.price_value * 0.27
WHERE pr.price_access LIKE CONCAT('%,', ug.group_id , ',%')
AND pr.price_value > 0
AND p.product_type = 'main'
";

/* AND pr.price_value > 0 AND p.product_type = 'main' is only used because I was unable to solve variants' price updating. */

$db->setQuery($sql);
$result = $db->execute();

$order->history = new stdClass();
$order->history->history_notified = 0;
$order->history->history_reason = 'Price recalculation made';
$order->history->history_type = 'modification';


$class->save($order);


Any help would be great to solve somehow to recalculate the variant's prices as well as we're not setting them up in the db now, just their parent's.

Thanks in advance!

PePe

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

  • Posts: 81598
  • Thank you received: 13082
  • MODERATOR
1 year 10 months ago #342977

Hi,

In $order->products you have an array of objects with data coming from the hikashop_order_product table in the database.
The product_type column is from the hikashop_product table in the database. So that's normal it doesn't work.
So if you want to know whether a product purchased in an order is a variant or not, you need to load the product data:

$productClass = hikashop_get('class.product');
$productData = $productClass->get($product->product_id);
echo $productData->product_type;

The following user(s) said Thank You: pepecortez

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

  • Posts: 171
  • Thank you received: 9
1 year 9 months ago #343505

Dear Nicolas,

Just noticed that if I use these lines of code it's calculating the total price correctly. But the VAT amount remains the same.
Is there any way to recalculate the VAT as well so simply?

nicolas wrote: Hi,

In a PHP action, you can use such code:

$class = hikashop_get('class.order');
$order = $class->get({order_id});
$class->save($order);
The save function will call the recalculateFullPrice function of class.order to save the updated total amount.

Last edit: 1 year 9 months ago by pepecortez.

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

  • Posts: 81598
  • Thank you received: 13082
  • MODERATOR
1 year 9 months ago #343510

Hi,

Most of the code in the recalculateFullPrice function is precisely to recalculate the total VAT.
The problem is that your code set order_product_price and order_product_tax but not order_product_tax_info which contains the details of the tax information for the product. And recalculateFullPrice bases itself on these details to recalculate the taxes appropriately.

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

  • Posts: 171
  • Thank you received: 9
1 year 9 months ago #343527

nicolas wrote: Hi,

Most of the code in the recalculateFullPrice function is precisely to recalculate the total VAT.
The problem is that your code set order_product_price and order_product_tax but not order_product_tax_info which contains the details of the tax information for the product. And recalculateFullPrice bases itself on these details to recalculate the taxes appropriately.


Yeah, I see it and understand, but it's not OK: if I modify the products on backend of an order (for exmaple modify a quantity, the VAT also not recalculated, it had to be done also manually, so it's not the missing of the mass action code as I see)

Please give me some advice, I need some urgent help to solve that, any forumthread, codepart or plugin for sample to understand the methodic how should be this done. (maybe mass action-> run after order modifcation, or a seperate plugin?)

Thanks your patience, help and answer in advance!

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

  • Posts: 81598
  • Thank you received: 13082
  • MODERATOR
1 year 9 months ago #343537

Hi,

No, you're not talking about the same thing.
In the interface, if you change the tax amount of a product in the interface, the total tax amount of the order will be recalculated. That's because the order_product_tax_info is updated by the system when you do so and then the recalculateFullPrice function recalulate the total tax based on this.

What you're saying is that if you change the price of a product in an order in the interface the tax is not recalculated for that product. And that's indeed the case. But that's not what you were talking about doing here. Your problematic is about updating the total tax amount, right ?

Unfortunately, I don't have a quick and dirty solution for you with the code you already have.
Instead of your update query, you need to loop through $order->products, load the price with another MySQL query, unserialize the order_product_tax_info, update the order_product_price, the order_product_tax and the order_product_tax_info, reserialize the order_product_tax_info and run an update query for each product to update these columns in the order_product table based on the order_product_id.

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

  • Posts: 27
  • Thank you received: 1
  • Hikashop Business
1 year 3 months ago #348487

Hi
Is this Mass Action usefull for updating more than 170.000 product prices? Is that possible at a server? Or is there a other solution?

I have now tried CSVI import but I have 7 sites with the same products. I am now working for many days to fix the update of 7 x 170.000 prices.

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

  • Posts: 81598
  • Thank you received: 13082
  • MODERATOR
1 year 3 months ago #348489

Hi,

First, it doesn't seem that your message is directly linked to what we're talking about in this thread.
In such a case, it would be better to open a new thread (you can always include a link to the this thread in the new thread as a reference).

The mass action system can be used to update the price of many products at once.
When you create / edit a mass action in the System>Mass actions menu, you can see a section "limitations" with two fields set respectively to 0 and 500. This means that the system will perform the actions on only the 500 first elements found. You can increase that value to process more elements at once. However, depending on how your server is configured, more than a few thousand elements at once should normally end in an error because of the "max execution time" or "memory limit" of the php.ini
You should be able to process 5000 products at once and thus, for 170 000 products, you would have to run the mass action a few hundred times. Not ideal, but better than one by one.

However, if you need to update all the prices at once for 170 000 products and the update is easy, the best is to directly write the MySQL query and run it via PHPMyAdmin.
For example, suppose you want to increase all the prices by 20%, you could just run the MySQL query below in your PHPMyAdmin:

UPDATE #__hikashop_price SET price_value = price_value*1.2
where #__ should be replaced by the table prefix of your Joomla configuration.
This will run in a few seconds maximum even for a few million prices.
Now the MySQL query might need to be more complex if there are different increases for different types of products, etc.
But for a single change to all the prices, this is by far the easiest and quickest.

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

Time to create page: 0.130 seconds
Powered by Kunena Forum