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-19273 extract code to get financial items and filter those already cancelled. #11300

Merged
merged 4 commits into from
Nov 24, 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
71 changes: 53 additions & 18 deletions CRM/Price/BAO/LineItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
*
* @package CRM
* @author Marshal Newrock <marshal@idealso.com>
* $Id$
*/

/**
Expand Down Expand Up @@ -756,10 +755,7 @@ public static function changeFeeSelections(
}
}

$trxnId = array();
if (!empty($trxn->id)) {
$trxnId['id'] = $trxn->id;
}
$trxnId = !empty($trxn->id) ? array('id' => $trxn->id) : array();
$lineItemObj->addFinancialItemsOnLineItemsChange($requiredChanges['line_items_to_add'], $entityID, $entityTable, $contributionId, $trxnId);

// update participant fee_amount column
Expand Down Expand Up @@ -821,18 +817,8 @@ protected function getReverseFinancialItemsToRecord($entityID, $entityTable, $co
return $financialItemsArray;
}

// gathering necessary info to record negative (deselected) financial_item
$updateFinancialItem = "
SELECT fi.*, SUM(fi.amount) as differenceAmt, price_field_value_id, financial_type_id, tax_amount
FROM civicrm_financial_item fi LEFT JOIN civicrm_line_item li ON (li.id = fi.entity_id AND fi.entity_table = 'civicrm_line_item')
WHERE (li.entity_table = '{$entityTable}' AND li.entity_id = {$entityID})
GROUP BY li.entity_table, li.entity_id, price_field_value_id, fi.id
";
$updateFinancialItemInfoDAO = CRM_Core_DAO::executeQuery($updateFinancialItem);
$financialItemResult = $updateFinancialItemInfoDAO->fetchAll();
$financialItemResult = $this->getNonCancelledFinancialItems($entityID, $entityTable);

$invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
$taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
foreach ($financialItemResult as $updateFinancialItemInfoValues) {
$updateFinancialItemInfoValues['transaction_date'] = date('YmdHis');
// the below params are not needed
Expand All @@ -847,7 +833,7 @@ protected function getReverseFinancialItemsToRecord($entityID, $entityTable, $co
$updateFinancialItemInfoValues['financialTrxn'] = $this->getRelatedCancelFinancialTrxn($previousFinancialItemID);
if ($previousLineItems[$updateFinancialItemInfoValues['entity_id']]['tax_amount']) {
$updateFinancialItemInfoValues['tax']['amount'] = -($previousLineItems[$updateFinancialItemInfoValues['entity_id']]['tax_amount']);
$updateFinancialItemInfoValues['tax']['description'] = $taxTerm;
$updateFinancialItemInfoValues['tax']['description'] = $this->getSalesTaxTerm();
if ($updateFinancialItemInfoValues['financial_type_id']) {
$updateFinancialItemInfoValues['tax']['financial_account_id'] = CRM_Contribute_BAO_Contribution::getFinancialAccountId($updateFinancialItemInfoValues['financial_type_id']);
}
Expand All @@ -863,7 +849,7 @@ protected function getReverseFinancialItemsToRecord($entityID, $entityTable, $co
isset($lineItemsToUpdate[$updateFinancialItemInfoValues['price_field_value_id']]['tax_amount'])
) {
$updateFinancialItemInfoValues['tax']['amount'] = $lineItemsToUpdate[$updateFinancialItemInfoValues['price_field_value_id']]['tax_amount'];
$updateFinancialItemInfoValues['tax']['description'] = $taxTerm;
$updateFinancialItemInfoValues['tax']['description'] = $this->getSalesTaxTerm();
if ($lineItemsToUpdate[$updateFinancialItemInfoValues['price_field_value_id']]['financial_type_id']) {
$updateFinancialItemInfoValues['tax']['financial_account_id'] = CRM_Contribute_BAO_Contribution::getFinancialAccountId($lineItemsToUpdate[$updateFinancialItemInfoValues['price_field_value_id']]['financial_type_id']);
}
Expand Down Expand Up @@ -1218,4 +1204,53 @@ protected function addFinancialItemsOnLineItemChange($isCreateAdditionalFinancia
return $changedFinancialTypeID;
}

/**
* Get Financial items, culling out any that have already been reversed.
*
* @param int $entityID
* @param string $entityTable
*
* @return array
* Array of financial items that have not be reversed.
*/
protected function getNonCancelledFinancialItems($entityID, $entityTable) {
$updateFinancialItem = "
SELECT fi.*, SUM(fi.amount) as differenceAmt, price_field_value_id, financial_type_id, tax_amount
FROM civicrm_financial_item fi LEFT JOIN civicrm_line_item li ON (li.id = fi.entity_id AND fi.entity_table = 'civicrm_line_item')
WHERE (li.entity_table = '{$entityTable}' AND li.entity_id = {$entityID})
GROUP BY li.entity_table, li.entity_id, price_field_value_id, fi.id
";
$updateFinancialItemInfoDAO = CRM_Core_DAO::executeQuery($updateFinancialItem);

$financialItemResult = $updateFinancialItemInfoDAO->fetchAll();
$items = array();
foreach ($financialItemResult as $index => $financialItem) {
$items[$financialItem['price_field_value_id']][$index] = $financialItem['amount'];

if (!empty($items[$financialItem['price_field_value_id']])) {
foreach ($items[$financialItem['price_field_value_id']] as $existingItemID => $existingAmount) {
if ($financialItem['amount'] + $existingAmount == 0) {
// Filter both rows as they cancel each other out.
unset($financialItemResult[$index]);
unset($financialItemResult[$existingItemID]);
unset($items['price_field_value_id'][$existingItemID]);
unset($items[$financialItem['price_field_value_id']][$index]);
}
}

}

}
return $financialItemResult;
}

/**
* Get the string used to describe the sales tax (eg. VAT, GST).
*
* @return string
*/
protected function getSalesTaxTerm() {
return CRM_Contribute_BAO_Contribution::checkContributeSettings('tax_term');
}

}
80 changes: 35 additions & 45 deletions tests/phpunit/CRM/Event/BAO/CRM19273Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Class CRM_Event_BAO_AdditionalPaymentTest
* @group headless
*/
class CRM_Event_BAO_CRM19273 extends CiviUnitTestCase {
class CRM_Event_BAO_CRM19273Test extends CiviUnitTestCase {

protected $_priceSetID;
protected $_cheapFee = 80;
Expand Down Expand Up @@ -100,6 +100,7 @@ protected function eventPriceSetCreate($feeTotal = 55, $minAmt = 0, $type = 'Tex
'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,
Expand All @@ -120,12 +121,10 @@ protected function eventPriceSetCreate($feeTotal = 55, $minAmt = 0, $type = 'Tex
* @return mixed
*/
private function contributionInvoice($contributionId) {

$query = "
SELECT SUM(line_total) total
FROM civicrm_line_item
WHERE entity_table = 'civicrm_participant'
AND entity_id = {$contributionId}";
WHERE contribution_id = {$contributionId}";
$dao = CRM_Core_DAO::executeQuery($query);

$this->assertTrue($dao->fetch(), "Succeeded retrieving invoicetotal");
Expand All @@ -140,19 +139,11 @@ private function contributionInvoice($contributionId) {
* @return mixed
*/
private function totalIncome($participantId) {

// @todo use INNER JOINS, this is not our style.
$query = "
SELECT SUM(et.amount) total
FROM civicrm_entity_financial_trxn et
, civicrm_financial_item fi
, civicrm_line_item li
WHERE et.entity_table='civicrm_financial_item'
AND fi.id = et.entity_id
AND fi.entity_table='civicrm_line_item'
AND fi.entity_id = li.id
AND li.entity_table = 'civicrm_participant'
AND li.entity_id = ${participantId}
SELECT SUM(fi.amount) total
FROM civicrm_financial_item fi
INNER JOIN civicrm_line_item li ON li.id = fi.entity_id AND fi.entity_table = 'civicrm_line_item'
WHERE li.entity_table = 'civicrm_participant' AND li.entity_id = ${participantId}
";
$dao = CRM_Core_DAO::executeQuery($query);

Expand All @@ -166,15 +157,15 @@ private function totalIncome($participantId) {
* @param float $amount
*/
private function balanceCheck($amount) {
$this->assertEquals($this->contributionInvoice($this->contributionID), $amount, "Invoice must a total of $amount");
$this->assertEquals($this->totalIncome($this->participantID), $amount, "The recorded income must be $amount ");
$this->assertEquals($this->totalIncome($this->contributionID), $amount, "The accumulated assets must be $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 ");
}

/**
* Prepare records for editing.
*/
public function registerParticipantAndPay() {
public function registerParticipantAndPay($actualPaidAmt = NULL) {
$params = array(
'send_receipt' => 1,
'is_test' => 0,
Expand All @@ -190,7 +181,7 @@ public function registerParticipantAndPay() {
$participant = $this->callAPISuccess('Participant', 'create', $params);
$this->_participantId = $participant['id'];

$actualPaidAmt = $this->_expensiveFee;
$actualPaidAmt = $actualPaidAmt ? $actualPaidAmt : $this->_expensiveFee;

$contributionParams = array(
'total_amount' => $actualPaidAmt,
Expand All @@ -216,61 +207,60 @@ public function registerParticipantAndPay() {
'contribution_id' => $this->_contributionId,
));

$PSparams['price_1'] = 1; // 1 is the option of the expensive room
$priceSetParams['price_1'] = 1; // 1 is the option of the expensive room
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_PriceSet::processAmount($this->_feeBlock, $PSparams, $lineItem);
CRM_Price_BAO_PriceSet::processAmount($this->_feeBlock, $priceSetParams, $lineItem);
$lineItemVal[$this->_priceSetID] = $lineItem;
CRM_Price_BAO_LineItem::processPriceSet($participant['id'], $lineItemVal, $contribution, 'civicrm_participant');

$this->contributionID = $this->callAPISuccessGetValue('Contribution', array('return' => 'id'));
$this->participantID = $this->callAPISuccessGetValue('Participant', array('return' => 'id'));
$this->balanceCheck($this->_expensiveFee);
}

public function testCRM19273() {
$PSparams['price_1'] = 2;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($PSparams, $this->participantID, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee);
$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, $this->_expensiveFee);
$this->balanceCheck($this->_cheapFee);

$PSparams['price_1'] = 1;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($PSparams, $this->participantID, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee);
$this->balanceCheck($this->_expensiveFee);
$priceSetParams['price_1'] = 1;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');

$PSparams['price_1'] = 3;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
// return here as the following lines will not work until the reset of PR 10962 has been merged.
return;

CRM_Price_BAO_LineItem::changeFeeSelections($PSparams, $this->participantID, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee);
$this->balanceCheck($this->_veryExpensive);
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee);
$this->balanceCheck($this->_expensiveFee);

$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, $this->_expensiveFee);
$this->balanceCheck($this->_veryExpensive);
}

/**
* Test that proper financial items are recorded for cancelled line items
*/
public function testCRM20611() {
$PSparams['price_1'] = 1;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID);
$priceSetParams['price_1'] = 1;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee);
$this->balanceCheck($this->_expensiveFee);

$PSparams['price_1'] = 2;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
CRM_Event_BAO_Participant::changeFeeSelections($PSparams, $this->participantID, $this->_contributionId, $this->_feeBlock, $lineItem, $this->_expensiveFee, $this->_priceSetID);
$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, $this->_expensiveFee);
$this->balanceCheck($this->_cheapFee);

//Complete the refund payment.
$submittedValues = array(
'total_amount' => 120,
'payment_instrument_id' => 3,
);
CRM_Contribute_BAO_Contribution::recordAdditionalPayment($this->_contributionId, $submittedValues, 'refund', $this->participantID);
CRM_Contribute_BAO_Contribution::recordAdditionalPayment($this->_contributionId, $submittedValues, 'refund', $this->_participantId);

// retrieve the cancelled line-item information
$cancelledLineItem = $this->callAPISuccessGetSingle('LineItem', array(
'entity_table' => 'civicrm_participant',
'entity_id' => $this->participantID,
'entity_id' => $this->_participantId,
'qty' => 0,
));
// retrieve the related financial lin-items
Expand Down