Skip to content

Commit

Permalink
Merge pull request #11300 from eileenmcnaughton/towards1
Browse files Browse the repository at this point in the history
CRM-19273 extract code to get financial items and filter those already cancelled.
  • Loading branch information
monishdeb authored Nov 24, 2017
2 parents b239a2d + e5e7a6a commit 87d1535
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 63 deletions.
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

0 comments on commit 87d1535

Please sign in to comment.