CRM-21577 add links to be able to add payments from the contribution block
authoreileen <emcnaughton@wikimedia.org>
Tue, 19 Dec 2017 01:36:08 +0000 (14:36 +1300)
committereileen <emcnaughton@wikimedia.org>
Tue, 19 Dec 2017 02:34:36 +0000 (15:34 +1300)
CRM/Contribute/BAO/Contribution.php
CRM/Contribute/Form/AbstractEditPayment.php
CRM/Contribute/Form/AdditionalPayment.php
templates/CRM/Contribute/Form/PaymentInfoBlock.tpl

index cf97cdf80dbc6ab85b404a8141dab70763c0135d..8f10d7c89d17db362d4970e7c1bb5b15ff542115 100644 (file)
@@ -4104,12 +4104,18 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']})
     }
 
     $paymentBalance = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($id, $entity, FALSE, $total);
-    $contributionIsPayLater = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'is_pay_later');
+    $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $id, 'return' => array('is_pay_later', 'contribution_status_id', 'financial_type_id')));
 
-    $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'financial_type_id');
+    $info['payLater'] = $contribution['is_pay_later'];
+    $info['contribution_status'] = $contribution['contribution_status'];
+
+    $financialTypeId = $contribution['financial_type_id'];
     $feeFinancialAccount = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($financialTypeId, 'Expense Account is');
 
-    if ($paymentBalance == 0 && $contributionIsPayLater) {
+    if ($paymentBalance == 0 && $info['payLater']) {
+      // @todo - review - this looks very unlikely to be correct.
+      // the balance should be correct based on payment transactions not
+      // assumptions.
       $paymentBalance = $total;
     }
 
@@ -4118,7 +4124,6 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']})
     $info['balance'] = $paymentBalance;
     $info['id'] = $id;
     $info['component'] = $component;
-    $info['payLater'] = $contributionIsPayLater;
     $rows = array();
     if ($getTrxnInfo && $baseTrxnId) {
       // Need to exclude fee trxn rows so filter out rows where TO FINANCIAL ACCOUNT is expense account
@@ -4197,6 +4202,8 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']})
       }
       $info['transaction'] = $rows;
     }
+
+    $info['payment_links'] = self::getContributionPaymentLinks($id, $paymentBalance, $info['contribution_status']);
     return $info;
   }
 
@@ -5476,6 +5483,63 @@ LIMIT 1;";
     }
   }
 
+  /**
+   * 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 float $balance
+   * @param string $contributionStatus
+   *
+   * @return array $actionLinks Links array containing:
+   *   -url
+   *   -title
+   */
+  protected static function getContributionPaymentLinks($id, $balance, $contributionStatus) {
+    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.
+      // (in some cases the contribution is 'Pending' and only the payment is failed. In those we
+      // do accept more payments agains them.
+      return array();
+    }
+    $actionLinks = array();
+    if ((int) $balance > 0) {
+      if (CRM_Core_Config::isEnabledBackOfficeCreditCardPayments()) {
+        $actionLinks[] = array(
+          'url' => CRM_Utils_System::url('civicrm/payment', array(
+            'action' => 'add',
+            'reset' => 1,
+            'id' => $id,
+            'mode' => 'live',
+          )),
+          'title' => ts('Submit Credit Card payment'),
+        );
+      }
+      $actionLinks[] = array(
+        'url' => CRM_Utils_System::url('civicrm/payment', array(
+          'action' => 'add',
+          'reset' => 1,
+          'id' => $id,
+        )),
+        'title' => ts('Record Payment'),
+      );
+    }
+    elseif ((int) $balance < 0) {
+      $actionLinks[] = array(
+        'url' => CRM_Utils_System::url('civicrm/payment', array(
+          'action' => 'add',
+          'reset' => 1,
+          'id' => $id,
+        )),
+        'title' => ts('Record Refund'),
+      );
+    }
+    return $actionLinks;
+  }
+
   /**
    * Assign Test Value.
    *
index be61e8a8a932aa428b2e98a8b995362fb175c838..c09e51d276ffc8ff098f15942d9fc36ccde48407 100644 (file)
@@ -95,6 +95,15 @@ class CRM_Contribute_Form_AbstractEditPayment extends CRM_Contact_Form_Task {
    */
   public $_id;
 
+  /**
+   * Entity that $this->_id relates to.
+   *
+   * If set the contact id is not required in the url.
+   *
+   * @var string
+   */
+  protected $entity;
+
   /**
    * The id of the premium that we are proceessing.
    *
@@ -217,6 +226,9 @@ class CRM_Contribute_Form_AbstractEditPayment extends CRM_Contact_Form_Task {
    */
   public function preProcess() {
     $this->_contactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
+    if (empty($this->_contactID) && !empty($this->_id) && $this->entity) {
+      $this->_contactID = civicrm_api3($this->entity, 'getvalue', array('id' => $this->_id, 'return' => 'contact_id'));
+    }
     $this->assign('contactID', $this->_contactID);
     CRM_Core_Resources::singleton()->addVars('coreForm', array('contact_id' => (int) $this->_contactID));
     $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add');
@@ -687,4 +699,24 @@ WHERE  contribution_id = {$id}
     }
   }
 
+
+  /**
+   * Assign the values to build the payment info block.
+   *
+   * @return string $title
+   *   Block title.
+   */
+  protected function assignPaymentInfoBlock() {
+    $paymentInfo = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_id, $this->_component, TRUE);
+    $title = ts('View Payment');
+    if (!empty($this->_component) && $this->_component == 'event') {
+      $info = CRM_Event_BAO_Participant::participantDetails($this->_id);
+      $title .= " - {$info['title']}";
+    }
+    $this->assign('transaction', TRUE);
+    $this->assign('payments', $paymentInfo['transaction']);
+    $this->assign('paymentLinks', $paymentInfo['payment_links']);
+    return $title;
+  }
+
 }
index 8d9ddf1779a3b02c19c0ab1a0345de69ae077a6d..574591c9ccf223bc0ed92f1e292a48b7a59d1e57 100644 (file)
@@ -49,6 +49,8 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
    */
   public $_id = NULL;
 
+  protected $entity = 'Contribution';
+
   protected $_owed = NULL;
 
   protected $_refund = NULL;
@@ -80,26 +82,18 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
 
   public function preProcess() {
 
-    parent::preProcess();
     $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE);
-    // @todo don't set this - rely on parent $this->contactID
-    $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
-    $this->_component = CRM_Utils_Request::retrieve('component', 'String', $this, TRUE);
+    parent::preProcess();
+    $this->_contactId = $this->_contactID;
+    $this->_component = CRM_Utils_Request::retrieve('component', 'String', $this, FALSE, 'contribution');
     $this->_view = CRM_Utils_Request::retrieve('view', 'String', $this, FALSE);
     $this->assign('component', $this->_component);
     $this->assign('id', $this->_id);
     $this->assign('suppressPaymentFormButtons', $this->isBeingCalledFromSelectorContext());
 
     if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
-      $paymentInfo = CRM_Contribute_BAO_Contribution::getPaymentInfo($this->_id, $this->_component, TRUE);
-      $title = ts('View Payment');
-      if ($this->_component == 'event') {
-        $info = CRM_Event_BAO_Participant::participantDetails($this->_id);
-        $title .= " - {$info['title']}";
-      }
+      $title = $this->assignPaymentInfoBlock();
       CRM_Utils_System::setTitle($title);
-      $this->assign('transaction', TRUE);
-      $this->assign('payments', $paymentInfo['transaction']);
       return;
     }
     $this->_fromEmails = CRM_Core_BAO_Email::getFromEmail();
@@ -138,10 +132,10 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
       CRM_Core_Error::fatal(ts('Credit card payment is not for Refund payments use'));
     }
 
-    list($this->_contributorDisplayName, $this->_contributorEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactId);
+    list($this->_contributorDisplayName, $this->_contributorEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
 
     $this->assign('contributionMode', $this->_mode);
-    $this->assign('contactId', $this->_contactId);
+    $this->assign('contactId', $this->_contactID);
     $this->assign('paymentType', $this->_paymentType);
     $this->assign('paymentAmt', abs($paymentAmt));
 
index 0296b19b29410a187d50b5984cae8264a31417e3..2d6e7d8a566ba9df90f368ab699bc13dc8379e9f 100644 (file)
@@ -55,4 +55,9 @@
    {/if}
    {ts 1=$entity}No payments found for this %1 record{/ts}
 {/if}
+
+  {foreach from=$paymentLinks item=paymentLink}
+    <a class="open-inline action-item crm-hover-button" href="{$paymentLink.url}">&raquo; {ts}{$paymentLink.title}{/ts}</a>
+  {/foreach}
+
 {/crmRegion}