We need to be able to set a shipping price based on the weight of the shipped items. I can set each rate to have a minimum or maximum weight, but not a range. This results in a bunch on rates appearing on the checkout that are not applicable.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jasonschweb created an issue. See original summary.

bojanz’s picture

Version: 8.x-2.0-beta4 » 8.x-2.x-dev

This should be done inside the ShipmentWeight condition.

bojanz’s picture

Title: Add ability to set ranges on shipping conditions » Expand the ShipmentWeight condition to support ranges
smartparty’s picture

StatusFileSize
new3.03 KB

This may help, we decided to create a separate ShipmentWeightRange condition to suit client needs.

mortona2k’s picture

Status: Active » Needs review
StatusFileSize
new6.43 KB
new71.91 KB

This patch takes some of the work from the previous and satisfies Bojan's request to extend the ShipmentWeight condition.

I included a patch from https://www.drupal.org/project/commerce_shipping/issues/2917519.

If we change the config array, we'll probably need an upgrade path? A test would be required as well.

Here's the form UI I came up with. I added conditions to min and max so you can set greater than or equal to - this may be overkill.
weight range screenshot

One potential change is adding a toggle to switch between single value and range.
Another is moving the weight unit above the min/max so it only has to be set once.

l_v’s picture

Hi, for me it doesn't work.
Here's the errors:

Notice: Undefined index: min_weight in Drupal\commerce_shipping\Plugin\Commerce\Condition\ShipmentWeight->buildConfigurationForm() (line 46 of modules/contrib/commerce_shipping/src/Plugin/Commerce/Condition/ShipmentWeight.php).

Notice: Undefined index: max_weight in Drupal\commerce_shipping\Plugin\Commerce\Condition\ShipmentWeight->buildConfigurationForm() (line 47 of modules/contrib/commerce_shipping/src/Plugin/Commerce/Condition/ShipmentWeight.php).

Notice: Undefined index: min_operator in Drupal\commerce_shipping\Plugin\Commerce\Condition\ShipmentWeight->buildConfigurationForm() (line 59 of modules/contrib/commerce_shipping/src/Plugin/Commerce/Condition/ShipmentWeight.php).

Notice: Undefined index: max_operator in Drupal\commerce_shipping\Plugin\Commerce\Condition\ShipmentWeight->buildConfigurationForm() (line 81 of modules/contrib/commerce_shipping/src/Plugin/Commerce/Condition/ShipmentWeight.php).

l_v’s picture

Ok, find out the problem: you are tryng to get not existing properties.
You should change:

$min_weight = $this->configuration['min_weight'];
$max_weight = $this->configuration['max_weight'];

in

$min_weight = $this->configuration['min']['min_weight'];
$max_weight = $this->configuration['max']['max_weight'];

and so on

bombjack’s picture

I have it running on my development site and it appears to be working fine.

I've re-rolled the patch to include the corrections made by I_v

ConradFlashback’s picture

@bombjack thanks, patch works well for me.

jbloomfield’s picture

@bombjack Thanks, the patch works perfectly.

mattjones86’s picture

I haven't tried this patch yet but I plan to give it a go shortly.

I'm wondering why the UI isn't just updated to allow multiple values similar to the ShipmentAddress condition? As far as I can see this is just a UI issue as ShipmentMethod->setConditions() already supports multiple weight conditions. You can do something like the following and this works in the checkout:


$lower_weight_condition = new ShipmentWeight([
  'operator' => '>',
  'weight' => [
    'number' => '1.00',
    'unit' => 'kg',
  ],
], 'shipment_weight', ['entity_type' => 'commerce_shipment']);


$upper_weight_condition = new ShipmentWeight([
  'operator' => '<=',
  'weight' => [
    'number' => '2.00',
    'unit' => 'kg',
  ],
], 'shipment_weight', ['entity_type' => 'commerce_shipment']);

$address_condition = new ShipmentAddress($zone_countries, 'shipment_address', ['entity_type' => 'commerce_shipment']);

$conditions = [
    $lower_weight_condition,
    $upper_weight_condition,
    $address_condition,
];

$method = ShippingMethod::create([
  'stores' => [1],
  'name' => 'Zone :zone - Up to :weightkg', [':zone' => $zone, ':weight' => '2.00']),
  'plugin' => [
    'target_plugin_id' => 'flat_rate',
    'target_plugin_configuration' => [
      'rate_label' => 'Zone :zone - Up to :weightkg', [':zone' => $zone, ':weight' => '2.00']),
      'rate_amount' => [
        'number' => '9.99',
        'currency_code' => 'GBP'
      ],
      'services' => [
        'default'
      ],
      'default_package_type' => 'custom_box',
    ],
  ],
  'status' => TRUE,
]);

$method->setConditions($conditions);
$method->setConditionOperator('AND');
$method->save();

mattjones86’s picture

Actually on further thought I can see this would need to be slightly different to the ShipmentAddress condition.

With ShipmentAddress, each individual territory is added in an OR group, such that any matching territory passes for the condition.

With ShipmentWeight, each weight restriction probably needs to be part of the AND group - or ideally configurable so you could select whether multiple weight conditions are restrictive or inclusive.

Anyway my point is that min and max does work for my use case, but I'm not sure it's configurable enough for everyone's use case.

sillo’s picture

Any eta on when shipping range will be implemented in Commerce Shipping?

This really an issue for shop owners that they cannot set shipping prices between 2 conditions - for example if price is above this, and below that.

Im praying this will be implemented soon.

I wish i was skilled enough to contribute, but im not.

sillo’s picture

I tried the #8 patch - it works perfect. I was hoping that shipping between 2 total prices would be present too.

How fast can this method be copied to support price ranges?

vanlindholm’s picture

Thanks #8 works for me. Note that I needed the patch in this issue to for the weight to be calculated: https://www.drupal.org/project/commerce_shipping/issues/2950520

hsponner’s picture

Thanks, #8 works for me, too.

markdc’s picture

Tested #8 and it works. Thank you!

bobemoe’s picture

#8 working great here too, didn't seem to need to use the patch mentioned in #15.
Cheers everyone :)

markdc’s picture

I think this needs work.

We got a complaint from a customer about too expensive shipping. Turns out the highest rate was being applied although his cart qualified for the lowest rate (we have 7 weight ranges set up). I tested it using a low weight item and it appropriately gave me the lowest rate. But when I refresh the page or proceed to the checkout review and go back, the highest rate is calculated and is stuck there.

bobemoe’s picture

@fatmarker tried to recreate your issue on my site (3 weight ranges with 2 options (signed and unsigned) in each range) and selected a product that falls into lowest range and it offers me correct price. I refresh and go forwards/backwards and navigate all about and it correctly sticks at the correct shipping price.

Do your ranges overlap maybe? Could you document them so we could take a look and try to recreate?

markdc’s picture

@bobemoe

Method 1: Greater than 0; Less than or equal to 6; 10€
Method 2: Greater than 6; Less than or equal to 10; 13€
Method 3: Greater than 10; Less than or equal to 14; 16€
Method 4: Greater than 14; Less than or equal to 20; 19€
Method 5: Greater than 20; Less than or equal to 25; 22€
Method 6: Greater than 25; Less than or equal to 30; 25€
Method 7: Greater than 30; Less than 9999; 30€

All methods include:
• Current order total less than 300€
• Shipping address, country = Austria

UPDATE
One detail I forgot to add and the cause of the problem: I had a package type with a weight of 30kg set up. And all the methods had that package type selected. Changing all to "Custom box" fixed the issue.

Maybe there should be a notification when a selected package type has a weight that conflicts with the weight range.

djg_tram’s picture

What's the status of this issue? Having ranges is so fundamental to shipping that it should be incorporated into the base module for sure. But if we patch now, can we be sure that the next upgrade won't redo the changes and make our shops non-functional overnight? Especially considering that the patch is two years (!) old now, and still not in the module?

I second what Mark said. The whole weight calculation is totally incompatible with package types. If you have any package type set, the shipment weight will be forced to the largest package weight and will be completely useless.

Oh no, Mark, that's not the case. I've just realized... There is no documentation, so we misunderstood. The weight specified for the package type isn't 30 kg. It isn't the max weight accepted by the postal service. It's the weight of the box itself. It will be added to the combined weight of the objects bought.

gaijinu’s picture

#8 works great, tested on commerce_shipping Version: 8.x-2.0-beta8

Please commit.

elc’s picture

Priority: Normal » Major
Status: Needs review » Reviewed & tested by the community

Patch in #8 works as advertised. RTBC as is; continue to work on issue to finish out any niggles.

Date range becomes mandatory. It might be worth making min or max optional when weight enabled so that it is not necessary to have a condition on ">= 0" or "<= 999999999" on either extreme of shipping rates.

Probably needs tests but this functionality is desperately needed in shops everywhere.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 8: commerce_shipping-shipment_weight_condition_range-2919113-8-d8.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

abx’s picture

Patch #8 Work. Tested with 8.x-2.x-dev updated 30 Jun 2020 at 13:03 UTC

benjarlett’s picture

the module commerce shipping weight tariff seems to have this sorted

j.’s picture

Patch #8 is working for great for me on 2.21.

usandul’s picture

Patch #8 Work. Tested with 8.x-2.1, Commerce - 2.25, Drupal 9.2.

andyd328’s picture

patch #8 also working on Core 9.3.3, Commerce 2.28, Commerce shipping 2.2.0

It generates a fatal error if the 'Shipment weight' condition is selected but no values are entered. I'm not sure what should happen in that case - maybe behave as if zero was entered?

kristofferrom’s picture

It's probably standard behaviour, but 8.x-2.3 overwrote the changes caused by patch #8 for me which broke the shipping methods and thus checkout for any orders with physical items. Redoing the patch on the new files fixed it. Just wanted to post it here in case anybody else were experiencing this too.

andyd328’s picture

Hi Kris,

It sounds as though you are manually patching the files. If you're using composer to build your site you can use "cweagans/composer-patches" to automate applying patches to the codebase. How to info is at https://github.com/cweagans/composer-patches .

petednz’s picture

Worked for me on Drupal core 9.4.3 if this feedback is still useful. I see this is still
'needs work'
presumably due to the "fatal error if the 'Shipment weight' condition is selected but no values are entered" mentioned by AndyD and ELC

kaszarobert’s picture

What is the error experienced in #30 precisely? After applying the patch I could only reproduce a InvalidArgumentException: Invalid weight unit "" provided. in Drupal\physical\WeightUnit::assertExists() (line 60 of modules/contrib/physical/src/WeightUnit.php). error. Probably because after applying the patch the min and max weight values are completely empty. Filling the missing weight values fixed that error. So to get this issue fixed, do we have to solve this in an update hook programmatically or should it be an update note for everyone who uses this condition must fix the weight values manually? Otherwise the patch works fine.

igork96’s picture

Status: Needs work » Needs review

I checked this issue and applied the patch from #8, and can confirm that is working and didn't have any issues.

thunders’s picture

StatusFileSize
new123.98 KB

After upgrading the Physical Fields module to 8.x-1.3 Patch in #8 gives an error. After the update, the Minimum and Maximum fields stopped appearing, and the old shipping methods did not work.

The problem occurs when modifying the Physical Fields module file NumberFormatterInterface.php

- public function format($number, array $options = []);
+ public function format(string $number, array $options = []): string;
and
- public function parse($number);
+ public function parse(string $number): string|bool;

abx’s picture

Just tested patch #8 again with Drupal 9.5.8 , Drupal Commerce 8.x-2.x-dev updated 7 Apr 2023

The patch still works.

I also found another module that can do the same thing here -> https://github.com/gnikolovski/commerce_gnikolovski

The module might be better for existing site since it provided you another new option Limit by shipment weight range in case you don't want current config to mixed up and got an error "Invalid weight unit "" provided." after patched.

meri_atanasovska’s picture

I tested and reviewed Patch #8 and I can confirm that it's solving this issue.

charles gantt’s picture

Status: Needs review » Reviewed & tested by the community

Patch in #8 works and resolves the issue. Marking RTBC!

alfthecat’s picture

Wow, what a blast from the past! I literally said a little prayer before hitting enter and applying the patch from #8. It applied and on top of that it's working. Absolutely saved my life, I did not expect commerce shipping to not be able to handle different shipping rates for different weights.

The commerce shipping tariff module is either not working (it's in alpha) or wasn't designed to cover this use case. There is a commerce shipping linear weight module, which in its current incarnation does not support a base rate and assumes the weight and price increments to be, well, linear. This patch was the last and only hope.

I now need to make 122 shipping methods (viva the entity_clone module!) to cover all the weight ranges, but at least with this patch we can get the required functionality working and deliver the site.

Legendary patch!

kaipipek’s picture

What is the schedule to get this feature into the production release?

jsacksick’s picture

Status: Reviewed & tested by the community » Needs work

Well the patch has failing tests... And doesn't respect coding standards, so it is not RTBC.
Additionally, anybody applying the patch with existing shipment weight conditions is going to experience issues with it (configuration is going to be lost).

This change is a breaking change, it needs to be backwards compatible to support existing shipping methods using this condition...

tBKoT made their first commit to this issue’s fork.

tbkot’s picture

Status: Needs work » Needs review
jsacksick’s picture

Status: Needs review » Needs work

I think the extra setting isn't required and make the UI more confusing...
We should probably simply override getComparisonOperators() to add extra operators.
Perhaps we should add "between" or 2 extra operators?

"< >" 
"<= >=" 

Not sure about the labels. Perhaps "Between (exclusive)" and "Between (inclusive)"?

tbkot’s picture

Status: Needs work » Needs review
abx’s picture

Status: Needs review » Reviewed & tested by the community

Just tested MR35 and it works great. New 2 options "Between (Inclusive)" and "Between (exclusive)" appear in the "Shipment > Shipment Weight -> Operator"

  • jsacksick committed d3937d2d on 8.x-2.x authored by tBKoT
    Issue #2919113: Expand the ShipmentWeight condition to support ranges
    
jsacksick’s picture

Status: Reviewed & tested by the community » Fixed

Merged! Thank you everyone!!

99gs3’s picture

Weight range is not available in commerce_shipping:8.x-2.9
And patch from #8 does not apply to commerce_shipping:8.x-2.9
Had to downgrade /src/Plugin/Commerce/Condition/ShipmentWeight.php to the version in commerce_shipping:8.x-2.8
Then apply patch #8.

jsacksick’s picture

How is that not available in 2.9? The change was committed? There are 2 new operators.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

stijnd’s picture

@99gs3 I also noticed this but now you can use the "Between" operator to set a weight range.
Thanks for the work everyone. Happy to see this patch can be ditched after 6 years!

jon pollard’s picture

Initially I also thought that this was not functioning - but then I realised that I needed to rebuild all of the shipping rules that were using weight to use the new operators.

The patch that we had previously did not require this and I think that's where confusion may arise.