Skip to content

Commit

Permalink
Merge pull request #15004 from davejenx/dev-core-860-discount-line-it…
Browse files Browse the repository at this point in the history
…ems-fix2

dev/core/issues/860: discount not applied to line item: call buildAmount hook in CRM_Member_Form_Membership::submit().
  • Loading branch information
eileenmcnaughton authored Aug 26, 2019
2 parents e590450 + 63b45b1 commit af20556
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CRM/Member/Form/Membership.php
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,12 @@ public function submit() {

$lineItem = [$this->_priceSetId => []];

// BEGIN Fix for dev/core/issues/860
// Prepare fee block and call buildAmount hook - based on CRM_Price_BAO_PriceSet::buildPriceSet().
CRM_Price_BAO_PriceSet::applyACLFinancialTypeStatusToFeeBlock($this->_priceSet['fields']);
CRM_Utils_Hook::buildAmount('membership', $this, $this->_priceSet['fields']);
// END Fix for dev/core/issues/860

CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
$formValues, $lineItem[$this->_priceSetId], NULL, $this->_priceSetId);

Expand Down
39 changes: 26 additions & 13 deletions CRM/Price/BAO/PriceSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -1014,19 +1014,9 @@ public static function buildPriceSet(&$form) {
else {
$feeBlock = &$form->_priceSet['fields'];
}
if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) {
foreach ($feeBlock as $key => $value) {
foreach ($value['options'] as $k => $options) {
if (!CRM_Core_Permission::check('add contributions of type ' . CRM_Contribute_PseudoConstant::financialType($options['financial_type_id']))) {
unset($feeBlock[$key]['options'][$k]);
}
}
if (empty($feeBlock[$key]['options'])) {
unset($feeBlock[$key]);
}
}
}
// call the hook.

self::applyACLFinancialTypeStatusToFeeBlock($feeBlock);
// Call the buildAmount hook.
CRM_Utils_Hook::buildAmount($component, $form, $feeBlock);

// CRM-14492 Admin price fields should show up on event registration if user has 'administer CiviCRM' permissions
Expand Down Expand Up @@ -1080,6 +1070,29 @@ public static function buildPriceSet(&$form) {
}
}

/**
* Apply ACLs on Financial Type to the price options in a fee block.
*
* @param array $feeBlock
* Fee block: array of price fields.
*
* @return void
*/
public static function applyACLFinancialTypeStatusToFeeBlock(&$feeBlock) {
if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) {
foreach ($feeBlock as $key => $value) {
foreach ($value['options'] as $k => $options) {
if (!CRM_Core_Permission::check('add contributions of type ' . CRM_Contribute_PseudoConstant::financialType($options['financial_type_id']))) {
unset($feeBlock[$key]['options'][$k]);
}
}
if (empty($feeBlock[$key]['options'])) {
unset($feeBlock[$key]);
}
}
}
}

/**
* Check the current Membership having end date null.
*
Expand Down
51 changes: 51 additions & 0 deletions tests/phpunit/CRM/Member/Form/MembershipTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,57 @@ public function testTwoInheritedMembershipsViaPriceSetInBackend() {
$this->assertEquals(1, $contributionResultAfterRelationshipDelete['count'], "Contribution has been wrongly deleted.");
}

/**
* dev/core/issues/860:
* Test creating two memberships via price set in the back end with a discount,
* checking that the line items have correct amounts.
*/
public function testTwoMembershipsViaPriceSetInBackendWithDiscount() {
// Register buildAmount hook to apply discount.
$this->hookClass->setHook('civicrm_buildAmount', [$this, 'buildAmountMembershipDiscount']);

// Create two memberships for individual $this->_individualId, via a price set in the back end.
$this->createTwoMembershipsViaPriceSetInBackEnd($this->_individualId);
$contribution = $this->callAPISuccessGetSingle('Contribution', [
'contact_id' => $this->_individualId,
]);
// Note: we can't check for the contribution total being discounted, because the total is set
// when the contribution is created via $form->testSubmit(), but buildAmount isn't called
// until testSubmit() runs. Fixing that might involve making testSubmit() more sophisticated,
// or just hacking total_amount for this case.

$lineItemResult = $this->callAPISuccess('LineItem', 'get', [
'contribution_id' => $contribution['id'],
]);
$this->assertEquals(2, $lineItemResult['count']);
$discountedItems = 0;
foreach ($lineItemResult['values'] as $lineItem) {
if (CRM_Utils_String::startsWith($lineItem['label'], 'Long Haired Goat')) {
$this->assertEquals(15.0, $lineItem['line_total']);
$this->assertEquals('Long Haired Goat - one leg free!', $lineItem['label']);
$discountedItems++;
}
}
$this->assertEquals(1, $discountedItems);
}

/**
* Implements hook_civicrm_buildAmount() for testTwoMembershipsViaPriceSetInBackendWithDiscount().
*/
public function buildAmountMembershipDiscount($pageType, &$form, &$amount) {
foreach ($amount as $id => $priceField) {
if (is_array($priceField['options'])) {
foreach ($priceField['options'] as $optionId => $option) {
if ($option['membership_type_id'] == 15) {
// Long Haired Goat membership discount.
$amount[$id]['options'][$optionId]['amount'] = $option['amount'] * 0.75;
$amount[$id]['options'][$optionId]['label'] = $option['label'] . ' - one leg free!';
}
}
}
}
}

/**
* Get a membership form object.
*
Expand Down

0 comments on commit af20556

Please sign in to comment.