Skip to content

Fix/table rate shipping by weight#2515

Open
zalito12 wants to merge 2 commits into
lunarphp:1.xfrom
zalito12:fix/table-rate-shipping-by-weight
Open

Fix/table rate shipping by weight#2515
zalito12 wants to merge 2 commits into
lunarphp:1.xfrom
zalito12:fix/table-rate-shipping-by-weight

Conversation

@zalito12

@zalito12 zalito12 commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Fix: Weight-based shipping rate tiers with ×100 scale and configurable weight_unit

Fix #2514

Problem

Weight-based shipping in lunarphp/table-rate-shipping is broken due to three issues:

  1. Scale mismatch: min_quantity for weight tiers is stored as a raw integer (e.g. 5 for 5 kg) but PricingManager::qty(int $qty) truncates floats like 2.5 to 2, causing tier matching failures and precision bugs.
  2. Hardcoded unit: The upstream fix (Fix weight-based shipping rate breakpoints evaluation #2382) hardcoded 'weight.kg' in the Converter call, ignoring the weight_unit attribute on ProductVariant. Products stored in grams or pounds would be incorrectly converted.
  3. No unit awareness in admin: The admin panel hardcodes "kg" in the suffix and helper text regardless of the configured weight unit.

Solution

Scale: ×100 — consistent with cart_total mode

Weight thresholds now use the same ×100 pattern as currency amounts in cart_total mode:

  • Admin enters: 2.5 kg → stored as 250 in min_quantity
  • Runtime computes: (int) round(2.5 * 100) = 250compares 250 >= 250

This eliminates PricingManager::qty(int) truncation and float precision issues entirely, since all values are integers.

Configurable weight_unit

ShipBy.php reads weight_unit from the shipping method's data JSON column (defaulting to 'kg'), and uses it to convert all product weights into the same unit before summing:

$weightUnit = $data['weight_unit'] ?? 'kg';
$tier = (int) round($cart->lines->sum(
    fn ($line) => $line->purchasable->weight->to("weight.{$weightUnit}")->convert()->getValue() * $line->quantity
) * 100);

The admin displays the selected weight_unit dynamically via a new getShippingWeightUnit() helper in label, suffix, and helper text.

Testing

  • All existing cart_total tests remain unchanged (no regression)
  • Existing weight tests updated to use ×100 min_quantity values
  • New test suite covers: configurable weight_unit, default fallback, data persistence, multi-unit conversion with ×100 scale

@zalito12 zalito12 force-pushed the fix/table-rate-shipping-by-weight branch from 0ad40a9 to fd4fec8 Compare June 13, 2026 07:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

Weight-based shipping rate tiers

2 participants