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

Fixes getTemplateContribution to use a more reliable way to load line items #20784

Merged
merged 1 commit into from
Jul 13, 2021
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
1 change: 0 additions & 1 deletion CRM/Contribute/BAO/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -2497,7 +2497,6 @@ public static function contributionCount($contactId, $includeSoftCredit = TRUE)
* The count is out on how correct related entities wind up in this case.
*/
protected static function repeatTransaction(array $input, array $contributionParams) {

$templateContribution = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution(
(int) $contributionParams['contribution_recur_id'],
array_filter([
Expand Down
62 changes: 11 additions & 51 deletions CRM/Contribute/BAO/ContributionRecur.php
Original file line number Diff line number Diff line change
Expand Up @@ -453,16 +453,25 @@ public static function getTemplateContribution(int $id, $overrides = []): array
}
if ($templateContributions->count()) {
$templateContribution = $templateContributions->first();
$lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($templateContribution['id']);
$order = new CRM_Financial_BAO_Order();
$order->setTemplateContributionID($templateContribution['id']);
$order->setOverrideFinancialTypeID($overrides['financial_type_id'] ?? NULL);
$order->setOverridableFinancialTypeID($templateContribution['financial_type_id']);
$order->setOverrideTotalAmount($overrides['total_amount'] ?? NULL);
$order->setIsPermitOverrideFinancialTypeForMultipleLines(FALSE);
$lineItems = $order->getLineItems();
// We only permit the financial type to be overridden for single line items.
// Otherwise we need to figure out a whole lot of extra complexity.
// It's not UI-possible to alter financial_type_id for recurring contributions
// with more than one line item.
// The handling of the line items is managed in BAO_Order so this
// is whether we should override on the contribution. Arguably the 2 should
// be decoupled.
if (count($lineItems) > 1 && isset($overrides['financial_type_id'])) {
unset($overrides['financial_type_id']);
}
$result = array_merge($templateContribution, $overrides);
$result['line_item'] = self::reformatLineItemsForRepeatContribution($result['total_amount'], $result['financial_type_id'], $lineItems, (array) $templateContribution);
$result['line_item'][$order->getPriceSetID()] = $lineItems;
// If the template contribution was made on-behalf then add the
// relevant values to ensure the activity reflects that.
$relatedContact = CRM_Contribute_BAO_Contribution::getOnbehalfIds($result['id']);
Expand Down Expand Up @@ -993,53 +1002,4 @@ public static function buildOptions($fieldName, $context = NULL, $props = []) {
return CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context);
}

/**
* Reformat line items for getTemplateContribution / repeat contribution.
*
* This is an extraction and may be subject to further cleanup.
*
* @param float $total_amount
* @param int $financial_type_id
* @param array $lineItems
* @param array $originalContribution
*
* @return array
*/
protected static function reformatLineItemsForRepeatContribution($total_amount, $financial_type_id, array $lineItems, array $originalContribution): array {
$lineSets = [];
if (count($lineItems) == 1) {
foreach ($lineItems as $index => $lineItem) {
if ($lineItem['financial_type_id'] != $originalContribution['financial_type_id']) {
// CRM-20685, Repeattransaction produces incorrect Financial Type ID (in specific circumstance) - if number of lineItems = 1, So this conditional will set the financial_type_id as the original if line_item and contribution comes with different data.
$financial_type_id = $lineItem['financial_type_id'];
}
if ($financial_type_id) {
// CRM-17718 allow for possibility of changed financial type ID having been set prior to calling this.
$lineItem['financial_type_id'] = $financial_type_id;
}
$taxAmountMatches = FALSE;
if ((!empty($lineItem['tax_amount']) && ($lineItem['line_total'] + $lineItem['tax_amount']) == $total_amount)) {
$taxAmountMatches = TRUE;
}
if ($lineItem['line_total'] != $total_amount && !$taxAmountMatches) {
// We are dealing with a changed amount! Per CRM-16397 we can work out what to do with these
// if there is only one line item, and the UI should prevent this situation for those with more than one.
$lineItem['line_total'] = $total_amount;
$lineItem['unit_price'] = round($total_amount / $lineItem['qty'], 2);
}
$priceField = new CRM_Price_DAO_PriceField();
$priceField->id = $lineItem['price_field_id'];
$priceField->find(TRUE);
$lineSets[$priceField->price_set_id][$lineItem['price_field_id']] = $lineItem;
}
}
// CRM-19309 if more than one then just pass them through:
elseif (count($lineItems) > 1) {
foreach ($lineItems as $index => $lineItem) {
$lineSets[$index][$lineItem['price_field_id']] = $lineItem;
}
}
return $lineSets;
}

}
Loading