Applying percentage discounts can sometimes lead to
EntityMetadataWrapperException: Unable to get the data property commerce_unit_price as the parent data structure is not set. in EntityStructureWrapper->getPropertyValue() (line 438 of /Users/Scott/Sites/wauwaa/sites/all/modules/entity/includes/entity.wrapper.inc).
After walking this through the issue seems to happen (in this instance) when related to commerce shipping/ commerce flat rate. The shipping calculation rules are firing and altering the shipping line items on the order at the same time as commerce discount is altering the discounted line items. There is a lot of conflict going on and its not merely a case of altering the rule weightings.
Traced this through into
foreach ($wrapper->commerce_line_items as $line_item_wrapper) {
if (!empty($line_item_types[$line_item_wrapper->type->value()])) {
$line_item_total = commerce_price_wrapper_value($line_item_wrapper, 'commerce_total', TRUE);
$calculated_discount += $line_item_total['amount'] * $rate;
}
}And the trouble is we can't always access $line_item_wrapper->type->value() on the line item. Therefore we need a check around this
something like
foreach ($wrapper->commerce_line_items as $line_item_wrapper) {
if ($line_item_wrapper->value()) {
if (!empty($line_item_types[$line_item_wrapper->type->value()])) {
$line_item_total = commerce_price_wrapper_value($line_item_wrapper, 'commerce_total', TRUE);
$calculated_discount += $line_item_total['amount'] * $rate;
}
}
}This appears to fix my issue whether its the right generic approach I'm not sure.
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | commerce_discount-empty_line_item_fix-2305695.patch | 748 bytes | subhojit777 |
| #1 | 2305695.patch | 1.07 KB | scotthooker |
Comments
Comment #1
scotthooker commentedComment #2
thehideki commentedThanks for the patch, seems to solve our issue.
Comment #3
joelpittetI did a quick check around commerce and other commerce modules to see how this is used and usually it's like this:
So I'm guessing there is a deeper problem here, or this needs to change in most of the other modules including commerce core.
At the very least you could do what commerce_shipping does and put both conditions in the same if statement.
eg:
What do you think?
Comment #4
kscheirerUse a try/catch block instead of testing for individual values. So the example above becomes
Comment #5
joelpittet@kscheirer what about
And that bigger problem I mentioned in #3 I think may be commerce_entitycache related.
Comment #6
joelpittet@scotthooker could you try this patch out? #2538812: When discounts are deleted on existing carts I hope it resolves your problem as well as they are very similar.
Comment #7
mglamanPostponing until we can see if #2538812: When discounts are deleted on existing carts resolved the issue reported in summary.
Patch in #1 doesn't match reported error of
Unable to get the data property commerce_unit_price as the parent data structure is not set. in EntityStructureWrapper->getPropertyValue(). It does work around the total.Comment #8
joelpittetClosing to triage the issue queue, reopen if you feel this still needs to be addressed.
If this is re-opened we need to add a test to ensure this issue doesn't re-surface.
Comment #9
subhojit777I am having the same problem. Although doing this:
Is supressing the exception, still I am trying to figure out why an empty line item is created in the first place.
Steps to reproduce:
- Create an order discount coupon
- Apply that coupon during checkout
- Refresh the checkout page
- You will see
And mysteriously a new null line item is created everytime you refersh the checkout page.
Comment #10
subhojit777After much debugging I found that it is happening because commerce_shipping adds a line item, and then deletes it. There are commerce_shipping rules which does that. I tried altering the weights of those rules and the discount rule, but it is not working.
Since, the order update causes causes
commerce_discount_commerce_cart_order_pre_refresh()to invoke, therefore, altering the priority of the rules is not going to work.This is the patch that should fix the issue.
Comment #11
czigor commented@subhojit777 Does that mean that we need commerce_shipping to reproduce the bug? I tried the steps in #9 but everything seemed to be fine, even with commerce_shipping enabled. I have the coupon redeem form on the first checkout step. Can you provide step-by-step instructions on how to reproduce this on a clean drupal site?
Comment #12
subhojit777Yes you need commerce_shipping to see the error. I have set breakpoints in the code and found that commerce_shipping add and later removes a line item. And commerce_discount getting a null line item throws. I saw this error in an existing site. I will try to reproduce the error on a fresh setup.