Commit 1cb09518 authored by eileen's avatar eileen

Fix unit test to not rely on hacking the DB to have ids for price sets & associated values

parent f4743a13
......@@ -602,6 +602,56 @@ WHERE li.contribution_id = %1";
}
}
/**
* Build the line items for the submitted price field.
*
* This is when first building them - not an update where an entityId is already present
* as this is intended as a subfunction of that. Ideally getLineItemArray would call this
* (resolving to the same format regardless of what type of price set is being used first).
*
* @param array $priceParams
* These are per the way the form processes them - ie
* ['price_1' => 1, 'price_2' => 8]
* This would mean price field id 1, option 1 (or 1 unit if using is_enter_qty).
* @param float|NULL $overrideAmount
* Optional override of the amount.
*
* @param int|NULL $financialTypeID
* Financial type ID is the type should be overridden.
*
* @return array
* Line items formatted for processing. These will look like
* [4] => ['price_field_id' => 4, 'price_field_value_id' => x, 'label....qty...unit_price...line_total...financial_type_id]
* [5] => ['price_field_id' => 5, 'price_field_value_id' => x, 'label....qty...unit_price...line_total...financial_type_id]
*
*/
public static function buildLineItemsForSubmittedPriceField($priceParams, $overrideAmount = NULL, $financialTypeID = NULL) {
$lineItems = array();
foreach ($priceParams as $key => $value) {
$priceField = self::getPriceFieldMetaData($key);
if ($priceField['html_type'] === 'Text') {
$valueSpec = reset($priceField['values']);
}
else {
$valueSpec = $priceField['values'][$value];
}
$qty = $priceField['is_enter_qty'] ? $value : 1;
$lineItems[$priceField['id']] = [
'price_field_id' => $priceField['id'],
'price_field_value_id' => $valueSpec['id'],
'label' => $valueSpec['label'],
'qty' => $qty,
'unit_price' => $overrideAmount ?: $valueSpec['amount'],
'line_total' => $qty * ($overrideAmount ?: $valueSpec['amount']),
'financial_type_id' => $financialTypeID ?: $valueSpec['financial_type_id'],
'membership_type_id' => $valueSpec['membership_type_id'],
'price_set_id' => $priceField['price_set_id'],
];
}
return $lineItems;
}
/**
* Function to update related contribution of a entity and
* add/update/cancel financial records
......@@ -1023,6 +1073,53 @@ WHERE li.contribution_id = %1";
}
}
/**
* Get the metadata for a price field.
*
* @param string|int $key
* Price field id. Either as an integer or as 'price_4' where 4 is the id
*
* @return array
* Metadata for the price field with a values key for option values.
*/
protected static function getPriceFieldMetaData($key) {
$priceFieldID = str_replace('price_', '', $key);
if (!isset(Civi::$statics[__CLASS__]['price_fields'][$priceFieldID])) {
$values = civicrm_api3('PriceFieldValue', 'get', [
'price_field_id' => $priceFieldID,
'return' => [
'id',
'amount',
'financial_type_id',
'membership_type_id',
'label',
'price_field_id',
'price_field_id.price_set_id',
'price_field_id.html_type',
'is_enter_qty',
],
]);
$firstValue = reset($values['values']);
$values = $values['values'];
foreach ($values as $index => $value) {
// Let's be nice to calling functions & ensure membership_type_id is set
// so they don't have to handle notices on it. Handle one place not many.
if (!isset($value['membership_type_id'])) {
$values[$index]['membership_type_id'] = NULL;
}
}
Civi::$statics[__CLASS__]['price_fields'][$priceFieldID] = [
'price_set_id' => $firstValue['price_field_id.price_set_id'],
'id' => $firstValue['price_field_id'],
'html_type' => $firstValue['price_field_id.html_type'],
'is_enter_qty' => !empty($firstValue['is_enter_qty']),
'values' => $values,
];
}
return Civi::$statics[__CLASS__]['price_fields'][$priceFieldID];
}
/**
* Helper function to retrieve financial trxn parameters to reverse
* for given financial item identified by $financialItemID
......
......@@ -9,6 +9,9 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
protected $_cheapFee = 80;
protected $_expensiveFee = 100;
protected $_veryExpensive = 120;
protected $expensiveFeeValueID;
protected $cheapFeeValueID;
protected $veryExpensiveFeeValueID;
/**
* @var int
......@@ -32,7 +35,6 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
*/
public function setUp() {
parent::setUp();
$this->cleanup();
$this->_contactId = $this->individualCreate();
$event = $this->eventCreate(array('is_monetary' => 1));
$this->_eventId = $event['id'];
......@@ -41,7 +43,6 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
$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);
$this->registerParticipantAndPay();
}
/**
......@@ -52,24 +53,6 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
$this->quickCleanUpFinancialEntities();
}
/**
* Remove default price field stuff.
*
* This is not actually good. However resolving this requires
* a lot more fixes & we have a bit of work to do on event tests.
*
* @throws \Exception
*/
protected function cleanup() {
$this->quickCleanup(
array(
'civicrm_price_field_value',
'civicrm_price_field',
'civicrm_price_set',
)
);
}
/**
* Create an event with a price set.
*
......@@ -129,6 +112,26 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
);
}
$field = CRM_Price_BAO_PriceField::create($paramsField);
$values = $this->callAPISuccess('PriceFieldValue', 'get', [
'price_field_id' => $field->id,
'return' => ['id', 'label']
]);
foreach ($values['values'] as $value) {
switch ($value['label']) {
case 'Expensive Room':
$this->expensiveFeeValueID = $value['id'];
break;
case 'Cheap Room':
$this->cheapFeeValueID = $value['id'];
break;
case 'Very Expensive':
$this->veryExpensiveFeeValueID = $value['id'];
break;
}
}
$this->priceSetFieldID = $field->id;
return $priceSet->id;
}
......@@ -224,28 +227,31 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
'contribution_id' => $this->_contributionId,
));
$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, $priceSetParams, $lineItem);
$lineItemVal[$this->_priceSetID] = $lineItem;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->expensiveFeeValueID;
$lineItems = CRM_Price_BAO_LineItem::buildLineItemsForSubmittedPriceField($priceSetParams);
CRM_Price_BAO_PriceSet::processAmount($this->_feeBlock, $priceSetParams, $lineItems);
$lineItemVal[$this->_priceSetID] = $lineItems;
CRM_Price_BAO_LineItem::processPriceSet($participant['id'], $lineItemVal, $this->getContributionObject($contribution['id']), 'civicrm_participant');
$this->balanceCheck($this->_expensiveFee);
}
public function testCRM19273() {
$priceSetParams['price_1'] = 2;
$this->registerParticipantAndPay();
$priceSetParams['price_' . $this->priceSetFieldID] = $this->cheapFeeValueID;
$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);
$priceSetParams['price_1'] = 1;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->expensiveFeeValueID;
$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);
$priceSetParams['price_1'] = 3;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->veryExpensiveFeeValueID;
$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);
......@@ -259,7 +265,7 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
$partiallyPaidContribuitonStatus = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Partially paid');
$this->assertEquals($this->callAPISuccessGetValue('Contribution', array('id' => $this->_contributionId, 'return' => 'contribution_status_id')), $partiallyPaidContribuitonStatus);
$priceSetParams['price_1'] = 3;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->veryExpensiveFeeValueID;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem);
$this->assertEquals($this->callAPISuccessGetValue('Contribution', array('id' => $this->_contributionId, 'return' => 'contribution_status_id')), $partiallyPaidContribuitonStatus);
......@@ -269,12 +275,13 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
* Test that proper financial items are recorded for cancelled line items
*/
public function testCRM20611() {
$priceSetParams['price_1'] = 1;
$this->registerParticipantAndPay();
$priceSetParams['price_' . $this->priceSetFieldID] = $this->expensiveFeeValueID;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem);
$this->balanceCheck($this->_expensiveFee);
$priceSetParams['price_1'] = 2;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->cheapFeeValueID;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->participantID, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem);
$this->balanceCheck($this->_cheapFee);
......@@ -313,16 +320,6 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
* 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);
......@@ -341,6 +338,7 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
'contact_id' => $this->_contactId,
);
$participant = $this->callAPISuccess('Participant', 'create', $params);
$this->_participantId = $participant['id'];
$contributionParams = array(
'total_amount' => 10,
'source' => 'Testset with information',
......@@ -363,21 +361,21 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
));
// CASE 1: Choose text price qty 1 (x$10 = $10 amount)
$priceSetParams['price_1'] = 1;
$priceSetParams['price_' . $this->priceSetFieldID] = 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, $this->getContributionObject($contribution['id']), '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);
$priceSetParams['price_' . $this->priceSetFieldID] = 3;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($participant['id'], 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $participant['id'], '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);
$priceSetParams['price_' . $this->priceSetFieldID] = 2;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($participant['id'], 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $participant['id'], 'participant', $this->_contributionId, $this->_feeBlock, $lineItem, 0);
$financialItems = $this->callAPISuccess('FinancialItem', 'Get', array(
'entity_table' => 'civicrm_line_item',
......@@ -421,20 +419,22 @@ class CRM_Event_BAO_ChangeFeeSelectionTest extends CiviUnitTestCase {
* CRM-17151: Test that Contribution status change to 'Completed' if balance is zero.
*/
public function testCRM17151() {
$this->registerParticipantAndPay();
$contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
$partiallyPaidStatusId = array_search('Partially paid', $contributionStatuses);
$pendingRefundStatusId = array_search('Pending refund', $contributionStatuses);
$completedStatusId = array_search('Completed', $contributionStatuses);
$this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $completedStatusId, 'Payment t be completed');
$priceSetParams['price_1'] = 2;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->cheapFeeValueID;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem);
$this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $pendingRefundStatusId, 'Contribution must be refunding');
$priceSetParams['price_1'] = 1;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->expensiveFeeValueID;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem);
$this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $completedStatusId, 'Contribution must, after complete payment be in state completed');
$priceSetParams['price_1'] = 3;
$priceSetParams['price_' . $this->priceSetFieldID] = $this->veryExpensiveFeeValueID;
$lineItem = CRM_Price_BAO_LineItem::getLineItems($this->_participantId, 'participant');
CRM_Price_BAO_LineItem::changeFeeSelections($priceSetParams, $this->_participantId, 'participant', $this->_contributionId, $this->_feeBlock, $lineItem);
$this->assertDBCompareValue('CRM_Contribute_BAO_Contribution', $this->_contributionId, 'contribution_status_id', 'id', $partiallyPaidStatusId, 'Partial Paid');
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment