verbb / postie

A Craft Commerce shipping calculator plugin.
Other
12 stars 18 forks source link

Round to 0 issues when converting lightweight products from lb to gram #126

Open joshuapease opened 6 months ago

joshuapease commented 6 months ago

Describe the bug

Hi again! I've run into another subtle issue with the same client who sells super small, lightweight products.

They have some products that weigh less than 0.001 lb = 0.454 g. The box packing process converts those weights to grams and stores them as an int. Due to how PHP rounds floats to integers, Item objects end up with a zero weight, and can produce issues with Providers (at least with FedEx Freight in our client's case).

image

Thanks to the custom packer from #123, I'm able to clamp those Item objects to weigh at least one gram. But, that can end up more than doubling the total weight (especially noticeable when ordering 50k products).


I don't know if there is an elegant workaround... since the Box Packer's Item interface expects grams as int.

In my very specific use case from #123, I'm merging similar Item objects together (adding up weight and value) and avoiding timeouts.

If I could somehow access the "true" weight as part of that merging step, I would be able to arrive at more accurate total weight.

Thought I'd share in case you had any insights. But don't feel like you need to spend a ton of time thinking about it.

Steps to reproduce

Here's how I produced the FedEx freight specific error in the screenshot.

  1. Create products with a weight equal to 0.001 lb or less.
  2. You may also need some heavier products too to trigger FedEx freight.
  3. Check out with low weight products.

So far I've only seen actual FedEx errors when the order order qualifies for FedEx freight.

For normal FedEx options, it doesn't seem to care about the weight being zero.

But either way... the weight is inaccurate.

Craft CMS version

4.7.0

Plugin version

3.1.6

Multi-site?

Yes

Additional context

No response

engram-design commented 6 months ago

Thanks for the feedback on this one! We're somewhat at the mercy of the item interface being an int, and using grams I thought would be pretty okay. I suppose we could round up with providers to the nearest gram (so 0.002 lb), but then I'm not sure how FedEx would treat that number, and would probably have its own limits. We wouldn't want to round up to 1lb which would be wildly inaccurate.

I'll do some testing.

hassanmah commented 6 months ago

@engram-design any updates on this? I have like 5000 lightweight products not showing rates from DHL, 0.086kg is being rounded to 0 for me

engram-design commented 5 months ago

I'm not entirely sure what sort of action to take here. We can't rightly round-up weights, as that produces invalid weight data, particularly for large orders, as you've both mentioned (5k, or 50k).

What I don't immediately understand though, is that if you're purchasing 50k 0.001 lb, is this an issue? That's 50 lb.

On the DHL end with @hassanmah the same stands. If we round up to even 0.1kg, order 5k products, that's 430kg.

We already check if the packed box is being rounded down to 0, and force it to be 0.01 unit (pounds, grams, whatever you providers weight unit is) here. I can bump that up to 0.1 but that's starting to push things.

One immediate change I could make is to make this unit-aware. Right now, it's 0.01 pounds or 0.01 grams depending on what unit the provider uses. This should probably be 0.01 grams, which is then converted to the provider unit, like other values are.

hassanmah commented 5 months ago

One way around this I found that convert KGs into grams for box packer to process, then convert back to KG for the DHL payload, this now brings back accurate rates

engram-design commented 5 months ago

I've gone ahead and made this change with setting the minimum weight for a box to 1g, which is them converted into the respective weight unit for the provider, which I'm hopeful should help.

And the conversation should already be happening, as the box packed takes whatever unit you have your products defined as, convert to metric (g/mm), then to the units the provider requires (for DHL, that's kg/cm).