diff --git a/commerce_discount.rules.inc b/commerce_discount.rules.inc index 542c298..dcd42c5 100644 --- a/commerce_discount.rules.inc +++ b/commerce_discount.rules.inc @@ -69,8 +69,8 @@ function commerce_discount_rules_condition_info() { 'base' => 'commerce_discount_date_condition', ); - $conditions['commerce_discount_compatibility_check'] = array( - 'label' => t('Check discount compatibility'), + $conditions['commerce_discount_compatibility_check_order'] = array( + 'label' => t('Check discount compatibility for order'), 'parameter' => array( 'commerce_order' => array( 'type' => 'commerce_order', @@ -89,6 +89,26 @@ function commerce_discount_rules_condition_info() { 'group' => t('Commerce Discount'), ); + $conditions['commerce_discount_compatibility_check_line_item'] = array( + 'label' => t('Check discount compatibility for line item'), + 'parameter' => array( + 'commerce_line_item' => array( + 'type' => 'commerce_line_item', + 'label' => t('Line item'), + 'description' => t('The line item the discount would be applied to.'), + 'wrapped' => TRUE, + ), + 'commerce_discount' => array( + 'type' => 'token', + 'label' => t('Discount'), + 'description' => t('A discount with a compatibility strategy that requires evaluation.'), + 'options list' => 'commerce_discount_entity_list', + 'wrapped' => TRUE, + ), + ), + 'group' => t('Commerce Discount'), + ); + if (module_exists('commerce_order')) { $conditions['commerce_order_compare_order_amount'] = array( 'label' => t('Order amount comparison'), @@ -424,7 +444,7 @@ function commerce_discount_rules_event_info() { } /** - * Rules callback: executes the "Check discount compatibility" condition. + * Rules callback: executes the "Check discount compatibility for order" condition. * * @param EntityDrupalWrapper $order_wrapper * The order the discount would be applied to. @@ -434,7 +454,7 @@ function commerce_discount_rules_event_info() { * @return bool * Returns TRUE if nothing has disqualified compatibility. */ -function commerce_discount_compatibility_check(EntityDrupalWrapper $order_wrapper, $discount_name) { +function commerce_discount_compatibility_check_order(EntityDrupalWrapper $order_wrapper, $discount_name) { // Ensure the discount we're loading still exists. if (!$discount = entity_load_single('commerce_discount', $discount_name)) { return FALSE; @@ -444,9 +464,46 @@ function commerce_discount_compatibility_check(EntityDrupalWrapper $order_wrappe $strategy = commerce_discount_get_compatibility_strategy($discount); // Determine which discounts have been applied to the order thus far. + // First a recalculation must be made to include previously applied discounts + $order = $order_wrapper->value(); + commerce_order_calculate_total($order); + // The wrapper has not been updated so we need to do that manually + $order_wrapper = entity_metadata_wrapper('commerce_order', $order); + // Now we can get the correct order total. $order_total = $order_wrapper->commerce_order_total->value(); $applied_discounts = commerce_discount_get_discounts_applied_to_price($order_total); + return _commerce_order_get_discount_compatibility($discount, $strategy, $applied_discounts); +} + +/** + * Rules callback: executes the "Check discount compatibility for line item" condition. + * + * @param EntityDrupalWrapper $line_item_wrapper + * The line item the discount would be applied to. + * @param string $discount_name + * The discount name whose compatibility needs to be checked. + * + * @return bool + * Returns TRUE if nothing has disqualified compatibility. + */ +function commerce_discount_compatibility_check_line_item(EntityDrupalWrapper $line_item_wrapper, $discount_name) { + // Ensure the discount we're loading still exists. + if (!$discount = entity_load_single('commerce_discount', $discount_name)) { + return FALSE; + } + + // Get the strategy from the compatibility strategy field. + $strategy = commerce_discount_get_compatibility_strategy($discount); + + // Determine which discounts have been applied to the line item thus far. + $unit_price = commerce_price_wrapper_value($line_item_wrapper, 'commerce_unit_price', TRUE); + $applied_discounts = commerce_discount_get_discounts_applied_to_price($unit_price); + + return _commerce_order_get_discount_compatibility($discount, $strategy, $applied_discounts); +} + +function _commerce_order_get_discount_compatibility($discount, $strategy, $applied_discounts) { // Ensure none of them indicate they are incompatible with the current one. foreach ($applied_discounts as $applied_discount_id => $applied_discount_name) { // Determine the strategy of the existing discount. diff --git a/commerce_discount.rules_defaults.inc b/commerce_discount.rules_defaults.inc index 3d21d7c..5cb05f9 100644 --- a/commerce_discount.rules_defaults.inc +++ b/commerce_discount.rules_defaults.inc @@ -50,10 +50,18 @@ function commerce_discount_default_rules_configuration() { // discount is compatible with any other discount, we need to prevent it // from being added if a previously applied discount indicates it is not // compatible with the current one. - $rule->condition('commerce_discount_compatibility_check', array( - 'commerce_order:select' => $type['entity type'] == 'commerce_order' ? 'commerce-order' : 'commerce-line-item:order', - 'commerce_discount' => $discount->name, - )); + if($discount->type === 'order_discount') { + $rule->condition('commerce_discount_compatibility_check_order', array( + 'commerce_order:select' => $type['entity type'] == 'commerce_order' ? 'commerce-order' : 'commerce-line-item:order', + 'commerce_discount' => $discount->name, + )); + } + elseif($discount->type === 'product_discount') { + $rule->condition('commerce_discount_compatibility_check_line_item', array( + 'commerce_line_item:select' => 'commerce-line-item', + 'commerce_discount' => $discount->name, + )); + } // Let other modules alter the rule object, with configuration specific // to commerce discount. We don't invoke an alter function, as it can