Skip to content

Commit

Permalink
Merge pull request #11380 from JMAConsulting/CRM-21513
Browse files Browse the repository at this point in the history
CRM-21513: Change fee selection for text price field on backoffice Event registration Not Creating Correct Financial Items
  • Loading branch information
eileenmcnaughton authored Dec 14, 2017
2 parents fbeb86d + 2661ce1 commit 03b9e33
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 34 deletions.
32 changes: 27 additions & 5 deletions CRM/Price/BAO/LineItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ public static function changeFeeSelections(
if (!empty($requiredChanges['line_items_to_cancel']) || !empty($requiredChanges['line_items_to_update'])) {
// @todo - this IF is to get this through PR merge but I suspect that it should not
// be necessary & is masking something else.
$financialItemsArray = $lineItemObj->getReverseFinancialItemsToRecord(
$financialItemsArray = $lineItemObj->getAdjustedFinancialItemsToRecord(
$entityID,
$entityTable,
$contributionId,
Expand Down Expand Up @@ -703,9 +703,7 @@ public static function changeFeeSelections(
$newFinancialItem = CRM_Financial_BAO_FinancialItem::create($updateFinancialItemInfoValues);
// record reverse transaction only if Contribution is Completed because for pending refund or
// partially paid we are already recording the surplus owed or refund amount
if (!empty($updateFinancialItemInfoValues['financialTrxn']) && ($contributionStatus == 'Completed'
)
) {
if (!empty($updateFinancialItemInfoValues['financialTrxn']) && ($contributionStatus == 'Completed')) {
$updateFinancialItemInfoValues = array_merge($updateFinancialItemInfoValues['financialTrxn'], array(
'entity_id' => $newFinancialItem->id,
'entity_table' => 'civicrm_financial_item',
Expand All @@ -720,6 +718,15 @@ public static function changeFeeSelections(
));
unset($updateFinancialItemInfoValues['financialTrxn']);
}
elseif (!empty($updateFinancialItemInfoValues['link-financial-trxn'])) {
civicrm_api3('EntityFinancialTrxn', 'create', array(
'entity_id' => $newFinancialItem->id,
'entity_table' => 'civicrm_financial_item',
'financial_trxn_id' => $trxn->id,
'amount' => $newFinancialItem->amount,
));
unset($updateFinancialItemInfoValues['link-financial-trxn']);
}
}
}

Expand All @@ -743,7 +750,7 @@ public static function changeFeeSelections(
* @return array
* List of formatted reverse Financial Items to be recorded
*/
protected function getReverseFinancialItemsToRecord($entityID, $entityTable, $contributionID, $priceFieldValueIDsToCancel, $lineItemsToUpdate) {
protected function getAdjustedFinancialItemsToRecord($entityID, $entityTable, $contributionID, $priceFieldValueIDsToCancel, $lineItemsToUpdate) {
$previousLineItems = CRM_Price_BAO_LineItem::getLineItems($entityID, str_replace('civicrm_', '', $entityTable));

$financialItemsArray = array();
Expand Down Expand Up @@ -773,6 +780,21 @@ protected function getReverseFinancialItemsToRecord($entityID, $entityTable, $co
// INSERT negative financial_items for tax amount
$financialItemsArray[$updateFinancialItemInfoValues['entity_id']] = $updateFinancialItemInfoValues;
}
// INSERT a financial item to record surplus/lesser amount when a text price fee is changed
elseif (!empty($lineItemsToUpdate) &&
$lineItemsToUpdate[$updateFinancialItemInfoValues['price_field_value_id']]['html_type'] == 'Text' &&
$updateFinancialItemInfoValues['amount'] > 0
) {
// calculate the amount difference, considered as financial item amount
$updateFinancialItemInfoValues['amount'] = $lineItemsToUpdate[$updateFinancialItemInfoValues['price_field_value_id']]['line_total'] - $totalFinancialAmount;
// add a flag, later used to link financial trxn and this new financial item
$updateFinancialItemInfoValues['link-financial-trxn'] = TRUE;
if ($previousLineItems[$updateFinancialItemInfoValues['entity_id']]['tax_amount']) {
$updateFinancialItemInfoValues['tax']['amount'] = $lineItemsToUpdate[$updateFinancialItemInfoValues['entity_id']]['tax_amount'] - $previousLineItems[$updateFinancialItemInfoValues['entity_id']]['tax_amount'];
$updateFinancialItemInfoValues['tax']['description'] = $this->getSalesTaxTerm();
}
$financialItemsArray[$updateFinancialItemInfoValues['entity_id']] = $updateFinancialItemInfoValues;
}
}

return $financialItemsArray;
Expand Down
2 changes: 1 addition & 1 deletion tests/phpunit/CRM/Dedupe/DedupeFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function testCustomRule() {
*/
public function testSupervisedDupes() {
$this->setupForGroupDedupe();
$ruleGroup = $this->callAPISuccessGetSingle('RuleGroup', array('s_reserved' => 1, 'contact_type' => 'Individual', 'used' => 'Supervised'));
$ruleGroup = $this->callAPISuccessGetSingle('RuleGroup', array('is_reserved' => 1, 'contact_type' => 'Individual', 'used' => 'Supervised'));
$foundDupes = CRM_Dedupe_Finder::dupesInGroup($ruleGroup['id'], $this->groupID);
// -------------------------------------------------------------------------
// default dedupe rule: threshold = 20 => (First + Last + Email) Matches ( 1 pair )
Expand Down
183 changes: 155 additions & 28 deletions tests/phpunit/CRM/Event/BAO/CRM19273Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function setUp() {
$this->_contactId = $this->individualCreate();
$event = $this->eventCreate(array('is_monetary' => 1));
$this->_eventId = $event['id'];
$this->_priceSetID = $this->eventPriceSetCreate();
$this->_priceSetID = $this->priceSetCreate();
CRM_Price_BAO_PriceSet::addTo('civicrm_event', $this->_eventId, $this->_priceSetID);
$priceSet = CRM_Price_BAO_PriceSet::getSetDetail($this->_priceSetID, TRUE, FALSE);
$priceSet = CRM_Utils_Array::value($this->_priceSetID, $priceSet);
Expand All @@ -52,7 +52,6 @@ public function tearDown() {
$this->quickCleanUpFinancialEntities();
}


/**
* Remove default price field stuff.
*
Expand All @@ -75,40 +74,60 @@ protected function cleanup() {
* Create an event with a price set.
*
* @todo resolve this with parent function.
*
* @param int $feeTotal
* @param int $minAmt
* @param string $type
*
* @return int
*/
protected function eventPriceSetCreate($feeTotal = 55, $minAmt = 0, $type = 'Text') {
$paramsSet['title'] = 'Two Options';
$paramsSet['name'] = CRM_Utils_String::titleToVar('Two Options');
protected function priceSetCreate($type = 'Radio') {
$feeTotal = 55;
$minAmt = 0;
$paramsSet['title'] = 'Two Options' . substr(sha1(rand()), 0, 4);
$paramsSet['name'] = CRM_Utils_String::titleToVar('Two Options') . substr(sha1(rand()), 0, 4);
$paramsSet['is_active'] = FALSE;
$paramsSet['extends'] = 1;

$priceSet = CRM_Price_BAO_PriceSet::create($paramsSet);

$paramsField = array(
'label' => 'Price Field',
'name' => CRM_Utils_String::titleToVar('Two Options'),
'html_type' => 'Radio',
//'price' => $feeTotal,
'option_label' => array('1' => 'Expensive Room', '2' => "Cheap Room", '3' => 'Very Expensive'),
'option_value' => array('1' => 'E', '2' => 'C', '3' => 'V'),
'option_name' => array('1' => 'Expensive', '2' => "Cheap", "3" => "Very Expensive"),
'option_weight' => array('1' => 1, '2' => 2, '3' => 3),
'option_amount' => array('1' => $this->_expensiveFee, '2' => $this->_cheapFee, '3' => $this->_veryExpensive),
'option_count' => array(1 => 1, 2 => 1, 3 => 1),
'is_display_amounts' => 1,
'weight' => 1,
'options_per_line' => 1,
'is_active' => array('1' => 1),
'price_set_id' => $priceSet->id,
'is_enter_qty' => 1,
'financial_type_id' => $this->getFinancialTypeId('Event Fee'),
);
if ($type == 'Text') {
$paramsField = array(
'label' => 'Text Price Field',
'name' => CRM_Utils_String::titleToVar('text_price_field'),
'html_type' => 'Text',
'option_label' => array('1' => 'Text Price Field'),
'option_name' => array('1' => CRM_Utils_String::titleToVar('text_price_field')),
'option_weight' => array('1' => 1),
'option_amount' => array('1' => 10),
'option_count' => array(1 => 1),
'is_display_amounts' => 1,
'weight' => 1,
'options_per_line' => 1,
'is_active' => array('1' => 1),
'price_set_id' => $priceSet->id,
'is_enter_qty' => 1,
'financial_type_id' => $this->getFinancialTypeId('Event Fee'),
);
}
else {
$paramsField = array(
'label' => 'Price Field',
'name' => CRM_Utils_String::titleToVar('Two Options'),
'html_type' => 'Radio',
//'price' => $feeTotal,
'option_label' => array('1' => 'Expensive Room', '2' => "Cheap Room", '3' => 'Very Expensive'),
'option_value' => array('1' => 'E', '2' => 'C', '3' => 'V'),
'option_name' => array('1' => 'Expensive', '2' => "Cheap", "3" => "Very Expensive"),
'option_weight' => array('1' => 1, '2' => 2, '3' => 3),
'option_amount' => array('1' => $this->_expensiveFee, '2' => $this->_cheapFee, '3' => $this->_veryExpensive),
'option_count' => array(1 => 1, 2 => 1, 3 => 1),
'is_display_amounts' => 1,
'weight' => 1,
'options_per_line' => 1,
'is_active' => array('1' => 1),
'price_set_id' => $priceSet->id,
'is_enter_qty' => 1,
'financial_type_id' => $this->getFinancialTypeId('Event Fee'),
);
}
$field = CRM_Price_BAO_PriceField::create($paramsField);
$this->priceSetFieldID = $field->id;
return $priceSet->id;
Expand Down Expand Up @@ -159,7 +178,6 @@ private function totalIncome($participantId) {
private function balanceCheck($amount) {
$this->assertEquals($amount, $this->contributionInvoice($this->_contributionId), "Invoice must a total of $amount");
$this->assertEquals($amount, $this->totalIncome($this->_participantId), "The recorded income must be $amount ");
$this->assertEquals($amount, $this->totalIncome($this->_contributionId), "The accumulated assets must be $amount ");
}

/**
Expand Down Expand Up @@ -278,4 +296,113 @@ public function testCRM20611() {
}
}

/**
* Test to ensure that correct financial records are entered on text price field fee change on event registration
*/
public function testCRM21513() {
$this->quickCleanup(
array(
'civicrm_price_field_value',
'civicrm_price_field',
'civicrm_price_set',
'civicrm_line_item',
'civicrm_financial_item',
)
);

$this->_priceSetID = $this->priceSetCreate('Text');
CRM_Price_BAO_PriceSet::addTo('civicrm_event', $this->_eventId, $this->_priceSetID);
$priceSet = CRM_Price_BAO_PriceSet::getSetDetail($this->_priceSetID, TRUE, FALSE);
$priceSet = CRM_Utils_Array::value($this->_priceSetID, $priceSet);
$this->_feeBlock = CRM_Utils_Array::value('fields', $priceSet);

$params = array(
'send_receipt' => 1,
'is_test' => 0,
'is_pay_later' => 0,
'event_id' => $this->_eventId,
'register_date' => date('Y-m-d') . " 00:00:00",
'role_id' => 1,
'status_id' => 1,
'source' => 'Event_' . $this->_eventId,
'contact_id' => $this->_contactId,
);
$participant = $this->callAPISuccess('Participant', 'create', $params);
$contributionParams = array(
'total_amount' => 10,
'source' => 'Testset with information',
'currency' => 'USD',
'non_deductible_amount' => 'null',
'receipt_date' => date('Y-m-d') . " 00:00:00",
'contact_id' => $this->_contactId,
'financial_type_id' => 4,
'payment_instrument_id' => 4,
'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_DAO_Contribution', 'contribution_status_id', 'Pending'),
'receive_date' => date('Y-m-d') . " 00:00:00",
'skipLineItem' => 1,
);

$contribution = CRM_Contribute_BAO_Contribution::create($contributionParams);
$this->_contributionId = $contribution->id;

$this->callAPISuccess('participant_payment', 'create', array(
'participant_id' => $this->_participantId,
'contribution_id' => $this->_contributionId,
));

// CASE 1: Choose text price qty 1 (x$10 = $10 amount)
$priceSetParams['price_1'] = 1;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_PriceSet::processAmount($this->_feeBlock, $priceSetParams, $lineItem);
$lineItemVal[$this->_priceSetID] = $lineItem;
CRM_Price_BAO_LineItem::processPriceSet($this->_participantId, $lineItemVal, $contribution, 'civicrm_participant');

// CASE 2: Choose text price qty 3 (x$10 = $30 amount)
$priceSetParams['price_1'] = 3;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, 0);

// CASE 3: Choose text price qty 2 (x$10 = $20 amount)
$priceSetParams['price_1'] = 2;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, 0);

$financialItems = $this->callAPISuccess('FinancialItem', 'Get', array(
'entity_table' => 'civicrm_line_item',
'entity_id' => array('IN' => array_keys($lineItem)),
'sequential' => 1,
));

$unpaidStatus = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Unpaid');
$expectedResults = array(
array(
'amount' => 10.00, // when qty 1 is used
'status_id' => $unpaidStatus,
'entity_table' => 'civicrm_line_item',
'entity_id' => 1,
),
array(
'amount' => 20.00, // when qty 3 is used, add the surplus amount i.e. $30 - $10 = $20
'status_id' => $unpaidStatus,
'entity_table' => 'civicrm_line_item',
'entity_id' => 1,
),
array(
'amount' => -10.00, // when qty 2 is used, add the surplus amount i.e. $20 - $30 = -$10
'status_id' => $unpaidStatus,
'entity_table' => 'civicrm_line_item',
'entity_id' => 1,
),
);
// Check if 3 financial items were recorded
$this->assertEquals(count($expectedResults), $financialItems['count']);
foreach ($expectedResults as $key => $expectedResult) {
foreach ($expectedResult as $column => $value) {
$this->assertEquals($expectedResult[$column], $financialItems['values'][$key][$column]);
}
}

$this->balanceCheck(20);
}

}

0 comments on commit 03b9e33

Please sign in to comment.