Programmatically changing Shipping in HikaShop v3.4

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #293906

-- HikaShop version -- : 3.4.0
-- Joomla version -- : 3.8.8
-- PHP version -- : 7.1.14

We're working on a store which has arrangements with a few of their manufacturers to ship new equipment from the Manufacturers themselves, while used equipment is shipped from our customer location or for OnSite Pickup, if their customer prefers.

Standard shipping from our customer's shop is a fixed cost based upon the weight of shipped items. Pickup is a standard Fee + a fixed amount per item. These were easy to set up.

However, some major Products must let the customer use a Custom Item Field to select between Curbside Delivery or Pickup.

If the item is NewCondition and from Manufacturer A, Curbside Delivery is $75.
If the item is NewCondition and from Manufacturers B or C, Curbside delivery is Free.

I suspect that I need a plugin which will test each item in the Cart Item list, and then add any extra fees to the Shipping totals (or add additional Shipping Definitions to the Cart and recalculate Shipping). I will probably also need to mask those Cart Items from the Shipping calculations that Hikashop performs so that their weight does not add additional fees to the rest of the cart.

I found a thread from a few years back, but it appears that the onBeforeCartSave() method may have been modified since then, and I haven't been able to get anything to work yet.

I'm guessing I need a hikashop group plugin that relies on onBeforeCartSave(), that replaces the cart_shipping_ids with a modified list, triggers a new Shipping calculation, and then uses

$class = hikashop_get('class.cart');
$class->get('reset_cache');

to get rid of old info.

So far, not a lot of luck with this route. Any other ideas, or examples, perhaps?
Any better ideas.

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

  • Posts: 12953
  • Thank you received: 1778
5 years 9 months ago #293934

Hello,

The best solution in your case will be to directly create your own shipping plugin which will handle these conditions :

However, some major Products must let the customer use a Custom Item Field to select between Curbside Delivery or Pickup.

If the item is NewCondition and from Manufacturer A, Curbside Delivery is $75.
If the item is NewCondition and from Manufacturers B or C, Curbside delivery is Free.


You can also check the code of our already developed shipping plugins.

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #293957

I've never written a Shipping plugin. It'll be a new adventure.

Thanks!

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294023

I have successfully written a shipping plugin that appears to match our requirements.

As those requirements are complex, I use the plugin to also assemble a simple object which contains enough information to write a simple explanation for the customer by modifying the View used to draw the checkout cart. However, I haven't found a way to pass that additional information along with the order so that I can reach it on the "checkout / show_block_cart.php" view.

I tried adding a property to the $order object, but the order information is apparently re-written as a $cart object for the template to use. I also could not find a way using the $message object.

Do you have some reliable method I can use to send this object from the Shipping Plugin to the Cart?
Perhaps I need to add a custom field to the Order or Cart?

Last edit: 5 years 9 months ago by icomex.

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

  • Posts: 12953
  • Thank you received: 1778
5 years 9 months ago #294042

Hello,

Can you give us more information about what you are trying to achieve through some screenshots for example, so that we can understand your issue ? Thank you.

Best regards,
Mohamed Thelji.

Last edit: 5 years 9 months ago by Mohamed Thelji.

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294062

OK, the nosebleed details:

I started with the code from Hikashop's "hikashopshipping/manual" plugin.

The new shipping plugin parses through each Order Item. It checks to see if a value has been selected by the user in an Item Custom Variable ($product_delivery) to choose a product-specific delivery method. If so, the Order Item gets routed through my custom code, which adds an appropriate value to the local variable $price (which the plugin uses to accumulate a final shipping charge for the Order ) based upon the delivery choice ($product_delivery may be either 'CURB' or 'FOB'), and whether the Order Item's product_condition is 'NewCondition'. The shipping charge amount is determined by the product_manufacturer_id and $product_delivery.

If the Order Item is NOT routed to my custom code (or does not meet the necessary conditions), the plugin uses its default code to build a normally processed value which is added to $price.

All of the code described so far is already working.

At the same time, all of these Order Item values (product_id, product_code, quantity, product_condition, manufacturer, the calculated shipping fee, and my custom variable product_delivery) are collected into one of three arrays stored within my own local variable, $shipping_description. Each property ( curd, fob, or standard ) contains an array of those Order Item values, indexed by the current Order Item's id value, the foreach loop's index variable $k.

The final structure of $shipping_description is something like this:

$shipping_description: 
Array
(
    [standard] => Array
        (
            [3487] => stdClass Object
                (
                    [product_id] => 172
                    [product_code] => DEF-001-A
                    [quantity] => 1
                    [shipping_charge] => 2
                )
        )
    [curb] => Array
        (
            [3488] => stdClass Object
                (
                    [product_id] => 857
                    [product_code] => ABC-001
                    [product_condition] => NewCondition
                    [delivery] => Curbside Delivery
                    [manufacturer] => ManufacturerA
                    [quantity] => 1
                    [shipping_charge] => 75
                )
        )
    [fob] => Array
        (
        )
)

I need to pass the contents of this shipping plugin local variable ($shipping_description) to the Custom View "checkout / show_block_cart.php" so that I can use the checkout cart display to explain the complicated shipping charges to the final customer.

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294079

I also see from testing that while the Shipping Total is being calculated correctly, the calculation of tax does not seem to be including this newly calculated shipping value when necessary. I'll add more details once I finish testing.

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

  • Posts: 12953
  • Thank you received: 1778
5 years 9 months ago #294101

Hello,

I think that checking the code of shipping plugins like UPS and AUPOST2 will probably help you.

The solution will be to directly do what you need through the "onShippingDisplay" trigger and return the good shipping price according what your customer have in his cart.

Kind regards,
Mohamed Thelji.

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294116

I have already done exactly that. (see my message above, where I explicitly stated that the price calculation is working.) Maybe I needed to add that the calculated price is correctly displaying in the rendered checkout cart and being stored correctly in the final order.

My main problem is that I need to pass additional information from that shipping calculation to the View template "checkout / show_block_cart" so that it can be displayed.

My secondary challenge is that the newly generated price is not being used to calculate tax when necessary, but I still believe I can beat that one.

The new variable, which I created to assemble that new information within the plugin, does not exist in the template. Creating new properties in the $order or $rate objects does not deliver them to the template (I thought that the plugin was working with Singleton objects, but apparently it either isn't, or the Shipping information is being rebuilt before the view is called). Perhaps this is an issue involving the shipping cache, which does not know about my new property.) I would prefer not resorting to a simple php $SESSION variable - I don't think that would be as secure or as stable as working within the environment of Hikashop.

I ask a third time: How can I transfer newly generated, custom information from a Shipping Plugin to a View?

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294126

I have discovered that the "checkout / show_block_shipping" view can receive my custom information by using the $shipping object. There is also apparently a $shipping_description property in that object (I never saw it mentioned in the hikashopshipping_manual plugin code, but it gets called and rendered in the "checkout / show_block_shipping " view, which appears above the cart), so I have renamed my custom variable to $shipping_details.

This is only a partial solution: It puts the information in front of the customer during checkout, but I would still prefer it to be written into the order so that it shows up on emailed cart displays, too.

Please keep thinking about a real solution while I implement this workaround.

Thanks.

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294134

The process of modifying the "checkout / show_block_shipping" View led me to how I could locate the custom information within the "checkout / she_block_cart" View. (For those following along, after adding the variable to $rate->shipping_details within my custom Shipping plugin, the custom variable could be reached within the variable $cart->shipping[0]->shipping_details ). Screenshot of the rendered details included.

Now that the major issue is put to bed, I still need to find out why my calculated value is not being used to calculate tax (when needed).

I would appreciate details on the tax calculation process within the plugin. A list of variables which are involved would be helpful.

Thanks.

Attachments:

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

  • Posts: 12953
  • Thank you received: 1778
5 years 9 months ago #294117

Hello,

My main problem is that I need to pass additional information from that shipping calculation to the View template "checkout / show_block_cart" so that it can be displayed.


In your case, passing your information by editing the "Order" object through the "onShippingDisplay" function will probably do the job :
		$order->order_shipping_params = new stdClass();
		$order->order_shipping_params->curb = $curb;
		$order->order_shipping_params->fob = $fob;
		$order->order_shipping_params->standard = $standard;

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294160

Please read my messages carefully. You have overlooked important details I have supplied.

From my third message in this thread:

"I tried adding a property to the $order object (*within the Shipping plugin), but the order information is apparently re-written as a $cart object for the template to use."


The template "checkout / show_block_default" has no data object which directly corresponds to the plugin's $order except $cart, which does not exist in the plugin's data space, and does not appear to carry custom data forward into the template in any identifiable way.

From my most recent message:

The process of modifying the "checkout / show_block_shipping" View led me to how I could locate the custom information within the "checkout / show_block_cart" View. (For those following along, after adding the variable to $rate->shipping_details within my custom Shipping plugin, the custom variable could be reached within the variable $cart->shipping[0]->shipping_details ). Screenshot of the rendered details included.

Now that the major issue is put to bed, I still need to find out why my calculated value is not being used to calculate tax (when needed).


I appreciate the suggestion in your last message (though I had already explored and dismissed that avenue), but - as I stated in my most recent message - I have solved that issue by using the Shipping plugin's $rates object, and am now only concerned with the fact that the newly calculated Shipping cost value within my Shipping plugin is transferring correctly to the cart's rendered display, but is not being used when taxes are calculated, (when needed).


If you'd like, I will start a new thread about that topic.

Regardless, I would appreciate details on the tax calculation process within the Shipping plugin. A list of variables which are involved would be helpful.

Thanks again.

Last edit: 5 years 9 months ago by icomex. Reason: Typo.

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

  • Posts: 12953
  • Thank you received: 1778
5 years 9 months ago #294181

Hello,

The template "checkout / show_block_default" has no data object which directly corresponds to the plugin's $order except $cart, which does not exist in the plugin's data space, and does not appear to carry custom data forward into the template in any identifiable way.


In that case, directly loading the cart and setting your parameters through the "cart_params" will do the job (it will be saved though your database "#_hikashop_cart" table).
Also, note that you'll have access to your shipping information through the "show_block_cart" file which will enable you to directly "generated" the data you need display on the cart.

Regardless, I would appreciate details on the tax calculation process within the Shipping plugin. A list of variables which are involved would be helpful.


Shipping methods prices are returned without taxes by the plugin.
The tax will then be added through the checkout workflow based on the "Product tax category" option of your shipping plugin.

Using that kind of code before returning your shipping price will probably do the job :
if(@$rates[$service_code]->shipping_tax_id && isset($YOUR_PRICE)) {
	$currencyClass = hikashop_get('class.currency');
	$YOUR_PRICE = $YOUR_PRICE,hikashop_getZone(),$rates[$service_code]->shipping_tax_id);
}

Checking the code of the "AuPost2" will probably help you.

Best regards,
Mohamed Thelji.

The following user(s) said Thank You: icomex

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294200

Wonderful. Thank you for the leads. I will check them out tonight.

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

  • Posts: 141
  • Thank you received: 3
  • Hikashop Business
5 years 9 months ago #294202

Success!

But first, you've got an error in the sample code you provided. It looks like there's a missing function call (and opening parenthesis) in the third line.

However, I suspect that the missing method is $currencyClass->getUntaxedPrice(), since I find similar nearly identical code in the "AuPost2" shipping plugin. There, code which is very similar to yours can be found within the addRate() method, which is used to build rates from a CURL call to the AU Postal service provider. Since I don't need that method, I placed your code within the onShippingDisplay() method's foreach loop which parses through the $rates object.

You speak of 'the "Product tax category" option of your shipping plugin', and it took me a while to find it. It isn't displayed unless the "Automatic Taxes" control is set to "no". I think that's a recent change, which you might need to remember when you're covering a topic like this.

Once I dug through those challenges, your code worked beautifully. My cart is now displaying my shipping details, calculating shipping costs properly, AND calculating the tax properly on the shipping charge.

I think this covers everything.

Thank you very much for your assistance.

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

Time to create page: 0.104 seconds
Powered by Kunena Forum