2

The goal is to allow the user to select the quantity they want, hit Add to Cart, then have the script separate the Line Item into individual Line Items with the Quantity of 1. I have accomplished this using Rule which works great but we also use Commerce Pricing Attributes which allows you to alter the price of a product before adding to cart. The altered price does not carry through to the split Line Items using this Rule. My script so far does keep that price.

This works for the first time the cart is loaded. The second time the cart is loaded, the original price is not applied to the added line items. Instead they remain in tack but get their default price applied.

Here is the shopping cart when it's first loaded after clicking the Cart link in the popup message. Everything appears OK with price across all items.

enter image description here

Here is what it looks like when I refresh the page, update cart, proceed to next step - pretty much anything that will trigger the commerce_cart_order_refresh().

enter image description here

As you can see the original item retains it's altered price, but the others that were added now default back to their original price.

Here is my code:

function ces_line_items_commerce_cart_line_item_refresh($line_item, $order_wrapper){
    // set the global user
    global $user;
    // load the entity wrapper of the line item
    $line_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
    // get the quantity of the line item
    $quantity = (int)$line_wrapper->quantity->value();
    // get the product id to use later
    $product_id = $line_wrapper->commerce_product->product_id->value();
    // set the altered price or current price of line item
    $newPrice = $line_wrapper->commerce_unit_price->amount->value();
    // get the original line item
    $old_line_item = $line_wrapper->line_item_id->value();
    // load the original line item -- need to do this for rewriting later
    $original_line_item = commerce_line_item_load($old_line_item);
    // set our index
    $i = 1;
    // only do the following if the original line item has a quantity above 1
    if($quantity > 1){
        // loop until we are 1 below quantity
        while($i < $quantity) {
            // it the product can be loaded
            if ($product = commerce_product_load($product_id)) {
                // create new line item
                $new_line_item = commerce_product_line_item_new($product, 1, $order_wrapper->order_id, $original_line_item->data);
                // make sure to include any additional price calculations
                drupal_alter('commerce_product_calculate_sell_price_line_item', $new_line_item);
                rules_invoke_event('commerce_product_calculate_sell_price', $new_line_item);
                // reload the line item
                $new_line_item = commerce_cart_product_add($user->uid, $new_line_item, FALSE);
                // set unit price
                $new_line_item->commerce_unit_price['und'][0]['amount'] = $newPrice;
                // set base price
                $new_line_item->commerce_unit_price['und'][0]['data']['components'][0]['price']['amount'] = $newPrice;
                // set base total amount
                $new_line_item->commerce_total['und'][0]['data']['components'][0]['price']['amount'] = $newPrice;
                // save new line item
                commerce_line_item_save($new_line_item);
                // add line item to order wrapper
                $order_wrapper->commerce_line_items[] = $new_line_item;
            }
            // increment our index      
            $i++;
        }
    }
    // alter line item quantity back to 1
    $original_line_item->quantity = "1.00";
    // save line item
    commerce_line_item_save($original_line_item);
}

So what I need is the ability to disable commerce_cart_order_refresh from trying to default everything back.

  • Your goal is to have each line item quantity always = 1 when user adds the same line item to the cart multiple times? – oksana-c Dec 1 '15 at 0:37
  • Yeah the option for the user to select the quantity of the product is still there, but once they click Add to Cart, I need it to break the line item created apart and create separate ones. I did this with Rules but the adjusted price didn't carry over. – Travis Johnston Dec 1 '15 at 12:55
  • This code does keep the proper price as it gets it from the first line item, but I can't seem to A) delete old line item or B) change the original quantity – Travis Johnston Dec 1 '15 at 12:56
  • Ah! http://drupal.stackexchange.com/questions/97404/new-line-item-every-time-an-item-is-added-avoid-grouping - have you tried this approach to keep line items separate? – oksana-c Dec 1 '15 at 16:51
  • Yeah you can see I actually posted my Rule in that one towards the bottom because the basic removal off the "combine" setting doesn't really do anything - even when removed from all locations. I had to make that rule. – Travis Johnston Dec 1 '15 at 16:57
4

You're approaching the problem incorrectly here. You shouldn't be trying to disable the cart order refresh. That includes things like discounts, taxes, etc. that may actually need to be applied to line items on the order in the future.

Instead, you should find a strategy to enrich the line item with the information it needs to reset the price to the proper custom price during the pricing process. This is the approach utilized in our old donation examples where customers can enter custom prices to donate:

https://drupalcommerce.org/videos/tutorials/donations-custom-line-item-types

I have no experience with the module you're using, so I can't say how to keep working within the framework it provides. Generally speaking, though, you could make this work by adding a price field to the line item called "Custom price" or something and then creating a pricing rule that sets the unit price of line items to the custom price at the appropriate point in time.

Alternately, you could store the necessary information in the data array of the line item, but then you'd still need a product pricing rule with a custom action that knows how to inspect the data array and reset the unit price to the appropriate amount.

  • I don't want to disable the refresh if I don't have too. My custom module works perfectly until the cart is refresh again, which is where I'm stuck. I am creating new line items with new pricing values, but the refresh disregards that and rebases them. I used Randy's video before because I also have Donations on the site. The Commerce Pricing Attributes with Product Attributes allow you to add discounts to your Products before adding to cart, but that is not done using a custom field in the line item so that wouldn't work in this case. Is there something I can pass to order_refresh? – Travis Johnston Jan 5 '16 at 16:17
  • Thanks Ryan! I am still using my module, the only difference now is I added a "New Price" field to my line item and added a line in my module to set a value on that field when it's adding the new line items to the cart. Then I made a new Calculate Sell Price of Product rule that says "if that field is filled in, use it to set the new unit price". And now it works with refreshes, etc. AWESOME! – Travis Johnston Jan 5 '16 at 17:23
  • Excellent - glad you got it sorted out. : ) – Ryan Szrama Jan 7 '16 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.