Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRM-21513: Change fee selection for text price field on backoffice Event registration Not Creating Correct Financial Items #11380

Merged
merged 2 commits into from
Dec 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}

}