I'm trying to create a rule that activates licenses (for digital download) when the checkout process is complete. I've got it working for any order being complete, but I can't add a condition that says 'only release the license if the customer selected attribute x'. I've tried entity exists by property, and entity has field.

Surely there must be a way in rules see if a given pricing attribute was selected in the completed order? Am I missing something obvious?

CommentFileSizeAuthor
attribute_rule.png238.29 KBmlmoseley

Comments

mlmoseley’s picture

After several hours of work, it's become clear to me that the pricing attributes a user selects on the product page are not passed to the cart. In other words, the shopping cart and in turn the order itself, have only only the total price, not the pricing attributes that make up that total.

In rules I turned full debug on and evaluated for the presence of the option set field. It came back false. I also dsm'd the entire $commerce_order variable, and the neither he value of the pricing attribute, not it's label, nor its machine name, were in that variable.

I'm coming to the conclusion that the pricing attributes are ephemeral. They appear only when viewing the product, calculations are made relative only when viewing the product, and when you leave the product page, those attributes are lost.

Please tell me if this is true or not, or point me toward how I can get the pricing attributes on the completed order screen.

mlmoseley’s picture

Priority: Normal » Major
mlmoseley’s picture

I figured out a solution. Will post it tomorrow .

mlmoseley’s picture

Okay, the solution is a little involved. I needed to be able to set a flag for a digital download when the customer selected one of the pricing attributes, but not the others. And the rule I was writing -- to release the DRM license -- needed to fire as a result of the check out process. So I had to get the attributes into the order.

And while the attributes were not in the order, they were in the line items that made up the order.

I ended up using hook__commerce_order_presave(). That gave me the order, I got the line item ids from it, loaded the line items iteratively and got the attributes, then set a flag on the order itself. That's why presave is so cool; it's for modifying the order before anything else does (except another presave hook that has a lower weight). I had the rule look for that flag

The attributes syntax is weird, but understandable. I did a simple search for the string I knew would exist if the person has chosen the attribute with the digital download. Here's the code, which I put in a module, not in template.php

function my_module_commerce_order_presave($order) {
    // set default - no download
    $order->my_module_download = false;
     // get all the line items
     if ((!empty($order->commerce_line_items)) && ($order->type != 'shipping')) {
        $line_item_array = $order->commerce_line_items[LANGUAGE_NONE];
        // iterate through them.
        foreach ($line_item_array as $key => $val) {
            $lnid = $val['line_item_id'];
            $ln = commerce_line_item_load($lnid);
            if ($ln->type == 'product') {
                $lnatt = $ln->commerce_pricing_attributes;
                if (strpos($lnatt,'s:1:"3"') !== false) {
                    $order->my_module_download = true;
                } else {
                        if (!$order->my_module_download) { 
                            $order->my_module_download = false;
                        }
                    }
            }
        }
    } 
    return $order; 
}