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

[REF] Add test for line item, extract fn #16402

Merged
merged 1 commit into from
Jan 30, 2020
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
2 changes: 1 addition & 1 deletion CRM/Price/BAO/LineItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ public static function getLineItemArray(&$params, $entityId = NULL, $entityTable
* 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
* @param float|null $overrideAmount
* Optional override of the amount.
*
* @param int|null $financialTypeID
Expand Down
166 changes: 93 additions & 73 deletions CRM/Price/BAO/PriceSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -676,79 +676,7 @@ public static function processAmount($fields, &$params, &$lineItem, $priceSetID
continue;
}

switch ($field['html_type']) {
case 'Text':
$firstOption = reset($field['options']);
$params["price_{$id}"] = [$firstOption['id'] => $params["price_{$id}"]];
CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, CRM_Utils_Array::value('partial_payment_total', $params));
$optionValueId = key($field['options']);

if (CRM_Utils_Array::value('name', $field['options'][$optionValueId]) === 'contribution_amount') {
$taxRates = CRM_Core_PseudoConstant::getTaxRates();
if (array_key_exists($params['financial_type_id'], $taxRates)) {
$field['options'][key($field['options'])]['tax_rate'] = $taxRates[$params['financial_type_id']];
$taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($field['options'][$optionValueId]['amount'], $field['options'][$optionValueId]['tax_rate']);
$field['options'][$optionValueId]['tax_amount'] = round($taxAmount['tax_amount'], 2);
}
}
if (!empty($field['options'][$optionValueId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionValueId, $totalTax);
}
$totalPrice += $lineItem[$firstOption['id']]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[key($field['options'])]);
break;

case 'Radio':
//special case if user select -none-
if ($params["price_{$id}"] <= 0) {
break;
}
$params["price_{$id}"] = [$params["price_{$id}"] => 1];
$optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);

// CRM-18701 Sometimes the amount in the price set is overridden by the amount on the form.
// This is notably the case with memberships and we need to put this amount
// on the line item rather than the calculated amount.
// This seems to only affect radio link items as that is the use case for the 'quick config'
// set up (which allows a free form field).
// @todo $priceSetID is a pseudoparam for permit override - we should stop passing it where we
// don't specifically need it & find a better way where we do.
$amount_override = NULL;

if ($priceSetID && count(self::filterPriceFieldsFromParams($priceSetID, $params)) === 1) {
$amount_override = CRM_Utils_Array::value('partial_payment_total', $params, CRM_Utils_Array::value('total_amount', $params));
}
CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, $amount_override);
if (!empty($field['options'][$optionValueId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionValueId, $totalTax);
if ($amount_override) {
$lineItem[$optionValueId]['line_total'] = $lineItem[$optionValueId]['unit_price'] = CRM_Utils_Rule::cleanMoney($lineItem[$optionValueId]['line_total'] - $lineItem[$optionValueId]['tax_amount']);
}
}
$totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
break;

case 'Select':
$params["price_{$id}"] = [$params["price_{$id}"] => 1];
$optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);

CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, CRM_Utils_Array::value('partial_payment_total', $params));
if (!empty($field['options'][$optionValueId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionValueId, $totalTax);
}
$totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
break;

case 'CheckBox':

CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, CRM_Utils_Array::value('partial_payment_total', $params));
foreach ($params["price_{$id}"] as $optionId => $option) {
if (!empty($field['options'][$optionId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionId, $totalTax);
}
$totalPrice += $lineItem[$optionId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionId]);
}
break;
}
list($params, $lineItem, $totalTax, $totalPrice) = self::getLine($params, $lineItem, $priceSetID, $field, $id, $totalPrice);
}

$amount_level = [];
Expand Down Expand Up @@ -1751,4 +1679,96 @@ protected static function reformatUsedByFormsWithEntityData($forms) {
return $usedBy;
}

/**
* Get the relevant line item.
*
* Note this is part of code being cleaned up / refactored & may change.
*
* @param array $params
* @param array $lineItem
* @param int $priceSetID
* @param array $field
* @param int $id
* @param float $totalPrice
*
* @return array
*/
protected static function getLine(&$params, &$lineItem, $priceSetID, $field, $id, $totalPrice): array {
$totalTax = 0;
switch ($field['html_type']) {
case 'Text':
$firstOption = reset($field['options']);
$params["price_{$id}"] = [$firstOption['id'] => $params["price_{$id}"]];
CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, CRM_Utils_Array::value('partial_payment_total', $params));
$optionValueId = key($field['options']);

if (CRM_Utils_Array::value('name', $field['options'][$optionValueId]) === 'contribution_amount') {
$taxRates = CRM_Core_PseudoConstant::getTaxRates();
if (array_key_exists($params['financial_type_id'], $taxRates)) {
$field['options'][key($field['options'])]['tax_rate'] = $taxRates[$params['financial_type_id']];
$taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($field['options'][$optionValueId]['amount'], $field['options'][$optionValueId]['tax_rate']);
$field['options'][$optionValueId]['tax_amount'] = round($taxAmount['tax_amount'], 2);
}
}
if (!empty($field['options'][$optionValueId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionValueId, $totalTax);
}
$totalPrice += $lineItem[$firstOption['id']]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[key($field['options'])]);
break;

case 'Radio':
//special case if user select -none-
if ($params["price_{$id}"] <= 0) {
break;
}
$params["price_{$id}"] = [$params["price_{$id}"] => 1];
$optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);

// CRM-18701 Sometimes the amount in the price set is overridden by the amount on the form.
// This is notably the case with memberships and we need to put this amount
// on the line item rather than the calculated amount.
// This seems to only affect radio link items as that is the use case for the 'quick config'
// set up (which allows a free form field).
// @todo $priceSetID is a pseudoparam for permit override - we should stop passing it where we
// don't specifically need it & find a better way where we do.
$amount_override = NULL;

if ($priceSetID && count(self::filterPriceFieldsFromParams($priceSetID, $params)) === 1) {
$amount_override = CRM_Utils_Array::value('partial_payment_total', $params, CRM_Utils_Array::value('total_amount', $params));
}
CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, $amount_override);
if (!empty($field['options'][$optionValueId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionValueId, $totalTax);
if ($amount_override) {
$lineItem[$optionValueId]['line_total'] = $lineItem[$optionValueId]['unit_price'] = CRM_Utils_Rule::cleanMoney($lineItem[$optionValueId]['line_total'] - $lineItem[$optionValueId]['tax_amount']);
}
}
$totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
break;

case 'Select':
$params["price_{$id}"] = [$params["price_{$id}"] => 1];
$optionValueId = CRM_Utils_Array::key(1, $params["price_{$id}"]);

CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, CRM_Utils_Array::value('partial_payment_total', $params));
if (!empty($field['options'][$optionValueId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionValueId, $totalTax);
}
$totalPrice += $lineItem[$optionValueId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionValueId]);
break;

case 'CheckBox':

CRM_Price_BAO_LineItem::format($id, $params, $field, $lineItem, CRM_Utils_Array::value('partial_payment_total', $params));
foreach ($params["price_{$id}"] as $optionId => $option) {
if (!empty($field['options'][$optionId]['tax_rate'])) {
$lineItem = self::setLineItem($field, $lineItem, $optionId, $totalTax);
}
$totalPrice += $lineItem[$optionId]['line_total'] + CRM_Utils_Array::value('tax_amount', $lineItem[$optionId]);
}
break;
}
return [$params, $lineItem, $totalTax, $totalPrice];
}

}
18 changes: 18 additions & 0 deletions tests/phpunit/CRM/Event/Form/ParticipantTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,24 @@ public function testSubmitWithPayment($thousandSeparator) {
$contribution = $this->callAPISuccessGetSingle('Contribution', []);
$this->assertEquals(1550.55, $contribution['total_amount']);
$this->assertEquals('Debit Card', $contribution['payment_instrument']);
$lineItem = $this->callAPISuccessGetSingle('LineItem', []);
$expected = [
'contribution_id' => $contribution['id'],
'entity_table' => 'civicrm_participant',
'qty' => 1,
'label' => 'big',
'unit_price' => 1550.55,
'line_total' => 1550.55,
'participant_count' => 0,
'price_field_id' => $this->_ids['price_field'][0],
'price_field_value_id' => $this->_ids['price_field_value'][1],
'tax_amount' => 0,
// Interestingly the financial_type_id set in this test is ignored but currently locking in what is happening with this test so setting to 'actual'
'financial_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Event Fee'),
];
foreach ($expected as $key => $value) {
$this->assertEquals($value, $lineItem[$key], $key);
}
}

/**
Expand Down