Comments

nicodh’s picture

Hi,

I'm very interesting in this feature, is this possible with this module ? If maintaners need help, I'm going to use this module for a commercial project which needs this feature, so of course I'm OK to bring my contribution !

Thanks

nicodh’s picture

I have looked the code, and I search a way to pass line items to the rule action commerce_price_table_set_price, and then calculate price with a kind of "context" : order's line items.
An idea ?

Cybso’s picture

Using a join on field_data_commerce_display_path in commerce_price_table_set_price (commerce_price_table.rules.inc) does the trick:

diff -r 81dde8b6a0af commerce_price_table.rules.inc
--- a/commerce_price_table.rules.inc    Fri Jan 04 21:08:53 2013 +0100
+++ b/commerce_price_table.rules.inc    Fri Jan 18 12:39:21 2013 +0100
@@ -29,6 +29,19 @@
 }
 
 function commerce_price_table_set_price($line_item, $quantity) {
+  // Apply discount when purchasing a mix of products from the same product display
+  if ($display_path = @$line_item->commerce_display_path['und'][0]['value']) {
+      $query = db_select('commerce_line_item', 'cli');
+      $query->addExpression('SUM(cli.quantity)', 'quantity');
+      $query->innerJoin('field_data_commerce_display_path', 'dp', 'dp.entity_id = cli.line_item_id');
+      $query->condition('cli.order_id', $line_item->order_id, '=');
+      $query->condition('dp.entity_type', 'commerce_line_item', '=');
+      $query->condition('dp.commerce_display_path_value', $display_path, '=');
+      if ($result = $query->execute()->fetchField()) {
+          $quantity = $result;
+      }
+  }
+
   // If the line item contains a product, we set the price according to the
   // quantity.
   if (commerce_line_items_quantity(array($line_item), commerce_product_line_item_types())) {

Update: Removed third parameter $price_table from the patch. I diff'ed it against my patch from http://drupal.org/node/1875688.

mattnorman2003’s picture

oh excellent, i'd forgotten about this but would still be useful, thanks Cybso, will test it out ASAP.

mattnorman2003’s picture

Tested and works exactly as required, thanks a lot.

Cybso’s picture

Status: Active » Needs review
StatusFileSize
new1.53 KB

I've added a boolean parameter to the rules action to enable or disable this behavior.

Cybso’s picture

Whoops... try this one ;-)

Cybso’s picture

And here's the same patch against "Expose price table to rules".

mattnorman2003’s picture

OK I have come across a stumbling block here, this solution works perfectly when creating orders through the shopping cart but doesn't work when creating an order manually through the back end.

Initially the price table didn't function at all when creating an order through the back end so I am using this module here ( http://drupal.org/project/commerce_checkout_admin ) to allow the rules that update prices from the price table to fire when an order is saved through the back end.

The reason it doesn't work is that $line_item->commerce_display_path is empty when not creating an order using the shopping cart, I'm not sure how to get around this.

Cybso’s picture

This is not easy, and since each product can be referred by multiple displays not intended by me (I only wanted to group all products of the same display).

I think it must be possible to join on field_data_commerce_product.entity_id (instead of field_data_commerce_display_path) and use the product_id to join on field_data_field_product.field_product_product_id to retrieve other products within the same displays (field_data_field_product.entity_id). This should be doable within one single SQL statement.

mattnorman2003’s picture

Thanks for the pointers - will give that a go.

mattnorman2003’s picture

ok this it what I have now - my php skills and knowledge of the commerce tables are pretty flaky so I suspect it's not very elegant but it seems to work!

        // Apply discount when purchasing a mix of products from the same product display
	if ($display_path = @$line_item->commerce_display_path['und'][0]['value']) {
		$query = db_select('commerce_line_item', 'cli');
		$query->addExpression('SUM(cli.quantity)', 'quantity');
		$query->innerJoin('field_data_commerce_display_path', 'dp', 'dp.entity_id = cli.line_item_id');
		$query->condition('cli.order_id', $line_item->order_id, '=');
		$query->condition('dp.entity_type', 'commerce_line_item', '=');
		$query->condition('dp.commerce_display_path_value', $display_path, '=');
		if ($result = $query->execute()->fetchField()) {
			$quantity = $result;
		}
	}
	else if (empty($line_item->commerce_display_path['und'][0]['value'])) {
		$query = db_select('field_data_commerce_product', 'fdcp');		
		$query->addExpression('SUM(cli.quantity)', 'quantity'); 
		$query->innerJoin('field_data_field_product', 'fdfp', 'fdfp.field_product_product_id = fdcp.commerce_product_product_id');
		$query->innerJoin('field_data_field_product', 'fdfp2', 'fdfp2.entity_id = fdfp.entity_id');
		$query->innerJoin('field_data_commerce_product', 'fdcp2', 'fdcp2.commerce_product_product_id = fdfp2.field_product_product_id');
		$query->innerJoin('commerce_line_item', 'cli', 'cli.line_item_id = fdcp2.entity_id');
		$query->innerJoin('field_data_commerce_line_items', 'fdcli', 'fdcli.commerce_line_items_line_item_id = cli.line_item_id and fdcli.entity_id = cli.order_id');
		$query->condition('fdcp.entity_id', $line_item->line_item_id, '=');
		$query->condition('cli.order_id', $line_item->order_id, '=');
		$query->condition('fdcp.entity_type', 'commerce_line_item', '=');
		$query->condition('fdcp.bundle', 'product', '=');
		$query->condition('fdfp.entity_type', 'node', '=');
		$query->condition('fdfp.bundle', 'product_display', '=');
		$query->condition('fdfp2.entity_type', 'node', '=');
		$query->condition('fdfp2.bundle', 'product_display', '=');
		$query->condition('fdcp2.entity_type', 'commerce_line_item', '=');
		$query->condition('fdcp2.bundle', 'product', '=');
		$query->condition('fdcli.entity_type', 'commerce_order', '=');
		$query->condition('fdcli.bundle', 'commerce_order', '=');
					
		if ($result = $query->execute()->fetchField()) {
			$quantity = $result;
		}
	}
	
pcambra’s picture

Just a recommendation, use EntityFieldQuery instead, you're doing too much db query assumptions there

T.Mardi’s picture

Hi Pedro, thanks for this great module.

I need this functionality and just wanted to check what patch I should be applying and testing?

I'm not sure what EntityFieldQuery is and how to add that to number #12.

Could you help please?

Thank you.

aaronglamb’s picture

Issue summary: View changes

I didn't use an EFQ, but above is a patch against the current release (7.x-1.1).