From f1b5e606d70ba25944ad194d7a2dd21e3c0e4ec3 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 10 Feb 2022 14:40:16 +1300 Subject: [PATCH 1/6] Tidy up getContributionPaymentLinks - removes an unused variable. - fixes to not show 'record Refund' for pending contributions (is displayed on the expand payments section of a contribution --- CRM/Contribute/BAO/Contribution.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 126527ebf9d1..5434ee955f9b 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -3634,7 +3634,7 @@ public static function getPaymentInfo($id, $component = 'contribution', $getTrxn $info['transaction'] = self::getContributionTransactionInformation($contributionId, $contribution['financial_type_id']); } - $info['payment_links'] = self::getContributionPaymentLinks($id, $paymentBalance, $info['contribution_status']); + $info['payment_links'] = self::getContributionPaymentLinks($id, $info['contribution_status']); return $info; } @@ -4275,7 +4275,6 @@ public static function updateMembershipBasedOnCompletionOfContribution($contribu * then a refund link. * * @param int $id - * @param float $balance * @param string $contributionStatus * * @return array @@ -4283,7 +4282,7 @@ public static function updateMembershipBasedOnCompletionOfContribution($contribu * -url * -title */ - protected static function getContributionPaymentLinks($id, $balance, $contributionStatus) { + protected static function getContributionPaymentLinks(int $id, string $contributionStatus): array { if ($contributionStatus === 'Failed' || !CRM_Core_Permission::check('edit contributions')) { // In general the balance is the best way to determine if a payment can be added or not, // but not for Failed contributions, where we don't accept additional payments at the moment. @@ -4314,15 +4313,17 @@ protected static function getContributionPaymentLinks($id, $balance, $contributi 'title' => ts('Submit Credit Card payment'), ]; } - $actionLinks[] = [ - 'url' => CRM_Utils_System::url('civicrm/payment', [ - 'action' => 'add', - 'reset' => 1, - 'id' => $id, - 'is_refund' => 1, - ]), - 'title' => ts('Record Refund'), - ]; + if ($contributionStatus !== 'Pending') { + $actionLinks[] = [ + 'url' => CRM_Utils_System::url('civicrm/payment', [ + 'action' => 'add', + 'reset' => 1, + 'id' => $id, + 'is_refund' => 1, + ]), + 'title' => ts('Record Refund'), + ]; + } return $actionLinks; } From 1d9d70d4c83e7a90ad1c03c330067ddf49b12126 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 10 Feb 2022 14:40:16 +1300 Subject: [PATCH 2/6] Tidy up getContributionPaymentLinks - removes an unused variable. - fixes to not show 'record Refund' for pending contributions (is displayed on the expand payments section of a contribution --- CRM/Contribute/BAO/Contribution.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 5434ee955f9b..d03f1abe93f0 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4271,9 +4271,6 @@ public static function updateMembershipBasedOnCompletionOfContribution($contribu /** * Get payment links as they relate to a contribution. * - * If a payment can be made then include a payment link & if a refund is appropriate - * then a refund link. - * * @param int $id * @param string $contributionStatus * @@ -4281,6 +4278,9 @@ public static function updateMembershipBasedOnCompletionOfContribution($contribu * $actionLinks Links array containing: * -url * -title + * + * If a payment can be made then include a payment link & if a refund is appropriate + * then a refund link. */ protected static function getContributionPaymentLinks(int $id, string $contributionStatus): array { if ($contributionStatus === 'Failed' || !CRM_Core_Permission::check('edit contributions')) { From 41edd535ca2a82fbc1ce72d1f2b78ec34bb85a7a Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Thu, 20 Jan 2022 22:17:03 +0000 Subject: [PATCH 3/6] Generate button links in PHP instead of smarty for ContributionView form --- CRM/Contribute/Form/ContributionView.php | 74 ++++++++++++++++++- .../CRM/Contribute/Form/ContributionView.tpl | 56 -------------- 2 files changed, 73 insertions(+), 57 deletions(-) diff --git a/CRM/Contribute/Form/ContributionView.php b/CRM/Contribute/Form/ContributionView.php index b99534b979a6..5655cad3de6b 100644 --- a/CRM/Contribute/Form/ContributionView.php +++ b/CRM/Contribute/Form/ContributionView.php @@ -55,6 +55,7 @@ public function preProcess() { } $this->assign('is_template', $values['is_template']); + $noACL = FALSE; if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus() && $this->_action & CRM_Core_Action::VIEW) { $financialTypeID = CRM_Contribute_PseudoConstant::financialType($values['financial_type_id']); CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'view'); @@ -69,7 +70,7 @@ public function preProcess() { } } elseif ($this->_action & CRM_Core_Action::VIEW) { - $this->assign('noACL', TRUE); + $noACL = TRUE; } CRM_Contribute_BAO_Contribution::resolveDefaults($values); @@ -230,6 +231,77 @@ public function preProcess() { $this->assign('component', 'contribution'); } $this->assignPaymentInfoBlock($id); + + $searchKey = NULL; + if ($this->controller->_key) { + $searchKey = $this->controller->_key; + } + if (( + CRM_Core_Permission::check('edit_contributions') + && CRM_Core_Permission::check('edit contributions of type ' . $financialTypeID) + && !empty($canEdit) + ) || (CRM_Core_Permission::check('edit contributions') && $noACL)) { + $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=update&context={$context}"; + if (($context === 'fulltext' || $context === 'search') && $searchKey) { + $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=update&context={$context}&key={$searchKey}"; + } + $linkButtons[] = [ + 'title' => ts('Edit'), + 'url' => 'civicrm/contact/view/contribution', + 'qs' => $urlParams, + 'icon' => 'fa-pencil', + 'accesskey' => 'e', + ]; + if (!empty($paymentButtonName)) { + $linkButtons[] = [ + 'title' => $paymentButtonName, + 'url' => 'civicrm/payment', + 'qs' => "action=add&reset=1&component=contribution&id={$id}&cid={$values['contact_id']}", + 'icon' => 'fa-plus-circle', + ]; + } + } + + if (( + CRM_Core_Permission::check('delete in CiviContribute') + && CRM_Core_Permission::check('delete contributions of type ' . CRM_Contribute_PseudoConstant::financialType($financialTypeID)) + && !empty($canDelete) + ) || (CRM_Core_Permission::check('delete in CiviContribute') && $noACL)) { + $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=delete&context={$context}"; + if (($context === 'fulltext' || $context === 'search') && $searchKey) { + $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=delete&context={$context}&key={$searchKey}"; + } + $linkButtons[] = [ + 'title' => ts('Delete'), + 'url' => 'civicrm/contact/view/contribution', + 'qs' => $urlParams, + 'icon' => 'fa-trash', + ]; + } + + $pdfUrlParams = "reset=1&id={$id}&cid={$values['contact_id']}"; + $emailUrlParams = "reset=1&id={$id}&cid={$values['contact_id']}&select=email"; + if ($invoicing && empty($is_template)) { + if (($values['contribution_status'] != 'Refunded') && ($values['contribution_status'] != 'Cancelled')) { + $invoiceButtonText = ts('Download Invoice'); + } + else { + $invoiceButtonText = ts('Download Invoice and Credit Note'); + } + $linkButtons[] = [ + 'title' => $invoiceButtonText, + 'url' => 'civicrm/contribute/invoice', + 'qs' => $pdfUrlParams, + 'icon' => 'fa-download', + ]; + $linkButtons[] = [ + 'title' => ts('Email Invoice'), + 'url' => 'civicrm/contribute/invoice/email', + 'qs' => $emailUrlParams, + 'icon' => 'fa-paper-plane', + ]; + } + $this->assign('linkButtons', $linkButtons ?? []); } /** diff --git a/templates/CRM/Contribute/Form/ContributionView.tpl b/templates/CRM/Contribute/Form/ContributionView.tpl index 751cb143869c..5b7b3b4fbd48 100644 --- a/templates/CRM/Contribute/Form/ContributionView.tpl +++ b/templates/CRM/Contribute/Form/ContributionView.tpl @@ -10,44 +10,6 @@
@@ -328,24 +290,6 @@ {/if}
- {if (call_user_func(array('CRM_Core_Permission','check'), 'edit contributions') && call_user_func(array('CRM_Core_Permission', 'check'), "edit contributions of type $financial_type") && $canEdit) || - (call_user_func(array('CRM_Core_Permission','check'), 'edit contributions') && $noACL)} - {assign var='urlParams' value="reset=1&id=$id&cid=$contact_id&action=update&context=$context"} - {if ( $context eq 'fulltext' || $context eq 'search' ) && $searchKey} - {assign var='urlParams' value="reset=1&id=$id&cid=$contact_id&action=update&context=$context&key=$searchKey"} - {/if} - {ts}Edit{/ts} - {if $paymentButtonName} - {ts}{$paymentButtonName}{/ts} - {/if} - {/if} - {if (call_user_func(array('CRM_Core_Permission','check'), 'delete in CiviContribute') && call_user_func(array('CRM_Core_Permission', 'check'), "delete contributions of type $financial_type") && $canDelete) || (call_user_func(array('CRM_Core_Permission','check'), 'delete in CiviContribute') && $noACL)} - {assign var='urlParams' value="reset=1&id=$id&cid=$contact_id&action=delete&context=$context"} - {if ( $context eq 'fulltext' || $context eq 'search' ) && $searchKey} - {assign var='urlParams' value="reset=1&id=$id&cid=$contact_id&action=delete&context=$context&key=$searchKey"} - {/if} - {ts}Delete{/ts} - {/if} {include file="CRM/common/formButtons.tpl" location="bottom"}
From de4bf21a9583d77dfb4497f643ce9ea1bb4e84b3 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 4 Feb 2022 12:37:45 +1300 Subject: [PATCH 4/6] Fix contribution view to use checkAccess --- CRM/Contribute/Form/ContributionView.php | 50 +++++++++++------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/CRM/Contribute/Form/ContributionView.php b/CRM/Contribute/Form/ContributionView.php index 5655cad3de6b..9f4bcd47f08d 100644 --- a/CRM/Contribute/Form/ContributionView.php +++ b/CRM/Contribute/Form/ContributionView.php @@ -24,6 +24,9 @@ class CRM_Contribute_Form_ContributionView extends CRM_Core_Form { /** * Set variables up before form is built. + * + * @throws \CRM_Core_Exception + * @throws \API_Exception */ public function preProcess() { $id = $this->getID(); @@ -55,23 +58,6 @@ public function preProcess() { } $this->assign('is_template', $values['is_template']); - $noACL = FALSE; - if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus() && $this->_action & CRM_Core_Action::VIEW) { - $financialTypeID = CRM_Contribute_PseudoConstant::financialType($values['financial_type_id']); - CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'view'); - if (CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'edit', FALSE)) { - $this->assign('canEdit', TRUE); - } - if (CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($id, 'delete', FALSE)) { - $this->assign('canDelete', TRUE); - } - if (!CRM_Core_Permission::check('view contributions of type ' . $financialTypeID)) { - CRM_Core_Error::statusBounce(ts('You do not have permission to access this page.')); - } - } - elseif ($this->_action & CRM_Core_Action::VIEW) { - $noACL = TRUE; - } CRM_Contribute_BAO_Contribution::resolveDefaults($values); if (!empty($values['contribution_page_id'])) { @@ -236,11 +222,8 @@ public function preProcess() { if ($this->controller->_key) { $searchKey = $this->controller->_key; } - if (( - CRM_Core_Permission::check('edit_contributions') - && CRM_Core_Permission::check('edit contributions of type ' . $financialTypeID) - && !empty($canEdit) - ) || (CRM_Core_Permission::check('edit contributions') && $noACL)) { + + if ($this->isHasAccess('update')) { $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=update&context={$context}"; if (($context === 'fulltext' || $context === 'search') && $searchKey) { $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=update&context={$context}&key={$searchKey}"; @@ -262,11 +245,7 @@ public function preProcess() { } } - if (( - CRM_Core_Permission::check('delete in CiviContribute') - && CRM_Core_Permission::check('delete contributions of type ' . CRM_Contribute_PseudoConstant::financialType($financialTypeID)) - && !empty($canDelete) - ) || (CRM_Core_Permission::check('delete in CiviContribute') && $noACL)) { + if ($this->isHasAccess('delete')) { $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=delete&context={$context}"; if (($context === 'fulltext' || $context === 'search') && $searchKey) { $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=delete&context={$context}&key={$searchKey}"; @@ -341,6 +320,23 @@ protected function assignPaymentInfoBlock($id) { return $title; } + /** + * @param string $action + * + * @return bool + */ + private function isHasAccess(string $action): bool { + try { + return Contribution::checkAccess() + ->setAction($action) + ->addValue('id', $this->getID()) + ->execute()->first()['access']; + } + catch (API_Exception $e) { + return FALSE; + } + } + /** * Get the contribution ID. * From 63db51f52d83f7e18a7c38889158c08ba9398b99 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 4 Feb 2022 19:13:03 +1300 Subject: [PATCH 5/6] Fix missing variables Note this updates the code such that the buttons are consistent on this form with the payment info block --- CRM/Contribute/BAO/Contribution.php | 8 +++-- CRM/Contribute/Form/ContributionView.php | 33 ++++++------------- .../CRM/Contribute/Form/ContributionView.tpl | 14 +++----- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index d03f1abe93f0..f086b14f5b0f 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4271,6 +4271,9 @@ public static function updateMembershipBasedOnCompletionOfContribution($contribu /** * Get payment links as they relate to a contribution. * + * If a payment can be made then include a payment link & if a refund is appropriate + * then a refund link. + * * @param int $id * @param string $contributionStatus * @@ -4279,10 +4282,9 @@ public static function updateMembershipBasedOnCompletionOfContribution($contribu * -url * -title * - * If a payment can be made then include a payment link & if a refund is appropriate - * then a refund link. + * @internal - not supported for use outside of core. */ - protected static function getContributionPaymentLinks(int $id, string $contributionStatus): array { + public static function getContributionPaymentLinks(int $id, string $contributionStatus): array { if ($contributionStatus === 'Failed' || !CRM_Core_Permission::check('edit contributions')) { // In general the balance is the best way to determine if a payment can be added or not, // but not for Failed contributions, where we don't accept additional payments at the moment. diff --git a/CRM/Contribute/Form/ContributionView.php b/CRM/Contribute/Form/ContributionView.php index 9f4bcd47f08d..f2d85975649a 100644 --- a/CRM/Contribute/Form/ContributionView.php +++ b/CRM/Contribute/Form/ContributionView.php @@ -202,20 +202,7 @@ public function preProcess() { ); $statusOptionValueNames = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $contributionStatus = $statusOptionValueNames[$values['contribution_status_id']]; - if (in_array($contributionStatus, ['Partially paid', 'Pending refund']) - || ($contributionStatus == 'Pending' && $values['is_pay_later']) - ) { - if ($contributionStatus == 'Pending refund') { - $this->assign('paymentButtonName', ts('Record Refund')); - } - else { - $this->assign('paymentButtonName', ts('Record Payment')); - } - $this->assign('addRecordPayment', TRUE); - $this->assign('contactId', $values['contact_id']); - $this->assign('componentId', $id); - $this->assign('component', 'contribution'); - } + $this->assign('addRecordPayment', in_array($contributionStatus, ['Partially paid', 'Pending refund', 'Pending'])); $this->assignPaymentInfoBlock($id); $searchKey = NULL; @@ -228,6 +215,10 @@ public function preProcess() { if (($context === 'fulltext' || $context === 'search') && $searchKey) { $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=update&context={$context}&key={$searchKey}"; } + foreach (CRM_Contribute_BAO_Contribution::getContributionPaymentLinks($this->getID(), $contributionStatus) as $paymentButton) { + $paymentButton['icon'] = 'fa-plus-circle'; + $linkButtons[] = $paymentButton; + } $linkButtons[] = [ 'title' => ts('Edit'), 'url' => 'civicrm/contact/view/contribution', @@ -235,14 +226,6 @@ public function preProcess() { 'icon' => 'fa-pencil', 'accesskey' => 'e', ]; - if (!empty($paymentButtonName)) { - $linkButtons[] = [ - 'title' => $paymentButtonName, - 'url' => 'civicrm/payment', - 'qs' => "action=add&reset=1&component=contribution&id={$id}&cid={$values['contact_id']}", - 'icon' => 'fa-plus-circle', - ]; - } } if ($this->isHasAccess('delete')) { @@ -260,7 +243,7 @@ public function preProcess() { $pdfUrlParams = "reset=1&id={$id}&cid={$values['contact_id']}"; $emailUrlParams = "reset=1&id={$id}&cid={$values['contact_id']}&select=email"; - if ($invoicing && empty($is_template)) { + if (Civi::settings()->get('invoicing') && !$contribution['is_template']) { if (($values['contribution_status'] != 'Refunded') && ($values['contribution_status'] != 'Cancelled')) { $invoiceButtonText = ts('Download Invoice'); } @@ -281,6 +264,10 @@ public function preProcess() { ]; } $this->assign('linkButtons', $linkButtons ?? []); + $this->assign('contactId', $values['contact_id']); + $this->assign('componentId', $id); + $this->assign('component', 'contribution'); + $this->assignPaymentInfoBlock($id); } /** diff --git a/templates/CRM/Contribute/Form/ContributionView.tpl b/templates/CRM/Contribute/Form/ContributionView.tpl index 5b7b3b4fbd48..7956686f7d95 100644 --- a/templates/CRM/Contribute/Form/ContributionView.tpl +++ b/templates/CRM/Contribute/Form/ContributionView.tpl @@ -178,18 +178,16 @@ {$thankyou_date|crmDate} {/if} + + {ts}Payment Summary{/ts} + + {if empty($is_template)} {ts}Payment Details{/ts} {include file="CRM/Contribute/Form/PaymentInfoBlock.tpl"} {/if} - {if $addRecordPayment} - - {ts}Payment Summary{/ts} - - - {/if} {if $softContributions && count($softContributions)} {* We show soft credit name with PCP section if contribution is linked to a PCP. *} @@ -285,9 +283,7 @@ {/if} -{if $addRecordPayment} - {include file="CRM/Contribute/Page/PaymentInfo.tpl" show='payments'} -{/if} +{include file="CRM/Contribute/Page/PaymentInfo.tpl" show='payments'}
{include file="CRM/common/formButtons.tpl" location="bottom"} From 9fa586c45c9f601d046306da6e0eb0713d8e4d8d Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 4 Feb 2022 19:51:35 +1300 Subject: [PATCH 6/6] Fix to not show payment for templates --- CRM/Contribute/Form/ContributionView.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CRM/Contribute/Form/ContributionView.php b/CRM/Contribute/Form/ContributionView.php index f2d85975649a..f523db876118 100644 --- a/CRM/Contribute/Form/ContributionView.php +++ b/CRM/Contribute/Form/ContributionView.php @@ -215,9 +215,11 @@ public function preProcess() { if (($context === 'fulltext' || $context === 'search') && $searchKey) { $urlParams = "reset=1&id={$id}&cid={$values['contact_id']}&action=update&context={$context}&key={$searchKey}"; } - foreach (CRM_Contribute_BAO_Contribution::getContributionPaymentLinks($this->getID(), $contributionStatus) as $paymentButton) { - $paymentButton['icon'] = 'fa-plus-circle'; - $linkButtons[] = $paymentButton; + if (!$contribution['is_template']) { + foreach (CRM_Contribute_BAO_Contribution::getContributionPaymentLinks($this->getID(), $contributionStatus) as $paymentButton) { + $paymentButton['icon'] = 'fa-plus-circle'; + $linkButtons[] = $paymentButton; + } } $linkButtons[] = [ 'title' => ts('Edit'), @@ -244,7 +246,7 @@ public function preProcess() { $pdfUrlParams = "reset=1&id={$id}&cid={$values['contact_id']}"; $emailUrlParams = "reset=1&id={$id}&cid={$values['contact_id']}&select=email"; if (Civi::settings()->get('invoicing') && !$contribution['is_template']) { - if (($values['contribution_status'] != 'Refunded') && ($values['contribution_status'] != 'Cancelled')) { + if (($values['contribution_status'] !== 'Refunded') && ($values['contribution_status'] !== 'Cancelled')) { $invoiceButtonText = ts('Download Invoice'); } else { @@ -264,6 +266,7 @@ public function preProcess() { ]; } $this->assign('linkButtons', $linkButtons ?? []); + // These next 3 parameters are used to construct a url in PaymentInfo.tpl $this->assign('contactId', $values['contact_id']); $this->assign('componentId', $id); $this->assign('component', 'contribution');