CRM-17751 add refund trxn to forms
authoreileen <emcnaughton@wikimedia.org>
Sun, 27 Dec 2015 09:18:37 +0000 (22:18 +1300)
committereileen <emcnaughton@wikimedia.org>
Wed, 30 Dec 2015 00:42:49 +0000 (13:42 +1300)
Change-Id: I8f4ad17cb2d7f9e33d853bbfc13d36fe5bacd572

Enotice fix

Change-Id: Ibea8a93291ad1963f108f5b80d7d55902ab61f66

CRM/Contribute/BAO/Contribution.php
CRM/Contribute/Form/Contribution.php
CRM/Contribute/Form/ContributionView.php
CRM/Core/BAO/FinancialTrxn.php
templates/CRM/Contribute/Form/Contribution.tpl
templates/CRM/Contribute/Form/ContributionView.tpl

index a42207dff19274dc614b84cd01458b0bb1d39cd4..8b888750ef09ad936eaf191a5c3f841f62e5d362 100644 (file)
@@ -291,6 +291,32 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
     return $null;
   }
 
+  /**
+   * Get the values and resolve the most common mappings.
+   *
+   * Since contribution status is resolved in almost every function that calls getValues it makes
+   * sense to have an extra function to resolve it rather than repeat the code.
+   *
+   * Think carefully before adding more mappings to be resolved as there could be performance implications
+   * if this function starts to be called from more iterative functions.
+   *
+   * @param array $params
+   *   Input parameters to find object.
+   *
+   * @return array
+   *   Array of the found contribution.
+   * @throws CRM_Core_Exception
+   */
+  public static function getValuesWithMappings($params) {
+    $values = $ids = array();
+    $contribution = self::getValues($params, $values, $ids);
+    if (is_null($contribution)) {
+      throw new CRM_Core_Exception('No contribution found');
+    }
+    $values['contribution_status'] = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $values['contribution_status_id']);
+    return $values;
+  }
+
   /**
    * Calculate net_amount & fee_amount if they are not set.
    *
@@ -3085,6 +3111,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
       $params['trxnParams'] = $trxnParams;
 
       if (!empty($params['prevContribution'])) {
+        $updated = FALSE;
         $params['trxnParams']['total_amount'] = $trxnParams['total_amount'] = $params['total_amount'] = $params['prevContribution']->total_amount;
         $params['trxnParams']['fee_amount'] = $params['prevContribution']->fee_amount;
         $params['trxnParams']['net_amount'] = $params['prevContribution']->net_amount;
@@ -3130,6 +3157,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
             $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount'];
             self::updateFinancialAccounts($params);
             $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id'];
+            $updated = TRUE;
           }
         }
 
@@ -3146,6 +3174,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
         ) {
           //Update Financial Records
           self::updateFinancialAccounts($params, 'changedStatus');
+          $updated = TRUE;
         }
 
         // change Payment Instrument for a Completed contribution
@@ -3167,6 +3196,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
               self::updateFinancialAccounts($params, 'changePaymentInstrument');
               $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount'];
               self::updateFinancialAccounts($params, 'changePaymentInstrument');
+              $updated = TRUE;
             }
           }
           elseif ((!CRM_Utils_System::isNull($params['contribution']->payment_instrument_id) ||
@@ -3177,6 +3207,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
             self::updateFinancialAccounts($params, 'changePaymentInstrument');
             $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount'];
             self::updateFinancialAccounts($params, 'changePaymentInstrument');
+            $updated = TRUE;
           }
           elseif (!CRM_Utils_System::isNull($params['contribution']->check_number) &&
             $params['contribution']->check_number != $params['prevContribution']->check_number
@@ -3189,6 +3220,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
             $params['trxnParams']['check_number'] = $params['contribution']->check_number;
             $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount'];
             self::updateFinancialAccounts($params, 'changePaymentInstrument');
+            $updated = TRUE;
           }
         }
 
@@ -3203,6 +3235,22 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac
           //Update Financial Records
           $params['trxnParams']['from_financial_account_id'] = NULL;
           self::updateFinancialAccounts($params, 'changedAmount');
+          $updated = TRUE;
+        }
+
+        if (!$updated) {
+          // Looks like we might have a data correction update.
+          // This would be a case where a transaction id has been entered but it is incorrect &
+          // the person goes back in & fixes it, as opposed to a new transaction.
+          // Currently the UI doesn't support multiple refunds against a single transaction & we are only supporting
+          // the data fix scenario.
+          // CRM-17751.
+          if (isset($params['refund_trxn_id'])) {
+            $refundIDs = CRM_Core_BAO_FinancialTrxn::getRefundTransactionIDs($params['id']);
+            if ($refundIDs['trxn_id'] != $params['refund_trxn_id']) {
+              civicrm_api3('FinancialTrxn', 'create', array('id' => $refundIDs['financialTrxnId'], 'trxn_id' => $params['refund_trxn_id']));
+            }
+          }
         }
       }
 
index f53b31e5f05f4e0c875edc645a98fdd4e3f479e4..9c8477c05841c8d09b49747aaf1de101e989b6eb 100644 (file)
@@ -329,6 +329,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
     CRM_Contribute_Form_SoftCredit::setDefaultValues($defaults, $this);
 
     if ($this->_mode) {
+      // @todo - remove this function as the parent does it too.
       $config = CRM_Core_Config::singleton();
       // Set default country from config if no country set.
       if (empty($defaults["billing_country_id-{$this->_bltID}"])) {
@@ -415,7 +416,12 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
       $this->assign('is_pay_later', TRUE);
     }
     $this->assign('contribution_status_id', CRM_Utils_Array::value('contribution_status_id', $defaults));
-
+    if (CRM_Utils_Array::value('contribution_status_id', $defaults) == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded')) {
+      $defaults['refund_trxn_id'] = CRM_Core_BAO_FinancialTrxn::getRefundTransactionTrxnID($this->_id);
+    }
+    else {
+      $defaults['refund_trxn_id'] = isset($defaults['trxn_id']) ? $defaults['trxn_id'] : NULL;
+    }
     $dates = array(
       'receive_date',
       'receipt_date',
@@ -733,7 +739,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
     $this->addDateTime('cancel_date', ts('Cancelled / Refunded Date'), FALSE, array('formatType' => 'activityDateTime'));
 
     $this->add('textarea', 'cancel_reason', ts('Cancellation / Refund Reason'), $attributes['cancel_reason']);
-
+    $this->add('text', 'refund_trxn_id', ts('Transaction ID for the refund payment'));
     $element = $this->add('select',
       'payment_processor_id',
       ts('Payment Processor'),
index d89a611de29d6f9cbe3a297f3038c8e8d8d5fc5a..aa3e03b3fe671b85531d344e3111107566a768f5 100644 (file)
@@ -41,12 +41,12 @@ class CRM_Contribute_Form_ContributionView extends CRM_Core_Form {
    */
   public function preProcess() {
     $id = $this->get('id');
-    $values = $ids = array();
     $params = array('id' => $id);
     $context = CRM_Utils_Request::retrieve('context', 'String', $this);
     $this->assign('context', $context);
 
-    CRM_Contribute_BAO_Contribution::getValues($params, $values, $ids);
+    $values = CRM_Contribute_BAO_Contribution::getValuesWithMappings($params);
+
     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');
@@ -64,6 +64,8 @@ class CRM_Contribute_Form_ContributionView extends CRM_Core_Form {
       $this->assign('noACL', TRUE);
     }
     CRM_Contribute_BAO_Contribution::resolveDefaults($values);
+    // @todo - I believe this cancelledStatus is unused - if someone reaches the same conclusion
+    // by grepping then the next few lines can go.
     $cancelledStatus = TRUE;
     $status = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     if (CRM_Utils_Array::value('contribution_status_id', $values) == array_search('Cancelled', $status)) {
@@ -164,6 +166,9 @@ class CRM_Contribute_Form_ContributionView extends CRM_Core_Form {
       $campaigns = CRM_Campaign_BAO_Campaign::getCampaigns($campaignId);
       $values['campaign'] = $campaigns[$campaignId];
     }
+    if ($values['contribution_status'] == 'Refunded') {
+      $this->assign('refund_trxn_id', CRM_Core_BAO_FinancialTrxn::getRefundTransactionTrxnIDgi($id));
+    }
 
     // assign values to the template
     $this->assign($values);
index fcd8be489d519319a0866086d039274bc9309199..21eeaea4e01b0a1802b1b577364154f2f20b9d15 100644 (file)
@@ -143,16 +143,18 @@ class CRM_Core_BAO_FinancialTrxn extends CRM_Financial_DAO_FinancialTrxn {
    * NOTE: This should be moved to separate BAO for EntityFinancialTrxn when we start adding more code for that object.
    *
    * @param $entity_id
-   *   Id of the entity usually the contactID.
+   *   Id of the entity usually the contributionID.
    * @param string $orderBy
    *   To get single trxn id for a entity table i.e last or first.
    * @param bool $newTrxn
+   * @param string $whereClause
+   *   Additional where parameters
    *
    * @return array
    *   array of category id's the contact belongs to.
    *
    */
-  public static function getFinancialTrxnId($entity_id, $orderBy = 'ASC', $newTrxn = FALSE) {
+  public static function getFinancialTrxnId($entity_id, $orderBy = 'ASC', $newTrxn = FALSE, $whereClause = '') {
     $ids = array('entityFinancialTrxnId' => NULL, 'financialTrxnId' => NULL);
 
     $condition = "";
@@ -164,7 +166,7 @@ class CRM_Core_BAO_FinancialTrxn extends CRM_Financial_DAO_FinancialTrxn {
       $orderBy = CRM_Utils_Type::escape($orderBy, 'String');
     }
 
-    $query = "SELECT ceft.id, ceft.financial_trxn_id FROM `civicrm_financial_trxn` cft
+    $query = "SELECT ceft.id, ceft.financial_trxn_id, cft.trxn_id FROM `civicrm_financial_trxn` cft
 LEFT JOIN civicrm_entity_financial_trxn ceft
 ON ceft.financial_trxn_id = cft.id AND ceft.entity_table = 'civicrm_contribution'
 LEFT JOIN civicrm_entity_financial_trxn ceft1
@@ -172,6 +174,7 @@ ON ceft1.financial_trxn_id = cft.id AND ceft1.entity_table = 'civicrm_financial_
 LEFT JOIN civicrm_financial_item cfi ON ceft1.entity_table = 'civicrm_financial_item' and cfi.id = ceft1.entity_id
 WHERE ceft.entity_id = %1 AND (cfi.entity_table <> 'civicrm_financial_trxn' or cfi.entity_table is NULL)
 {$condition}
+{$whereClause}
 ORDER BY cft.id {$orderBy}
 LIMIT 1;";
 
@@ -180,10 +183,33 @@ LIMIT 1;";
     if ($dao->fetch()) {
       $ids['entityFinancialTrxnId'] = $dao->id;
       $ids['financialTrxnId'] = $dao->financial_trxn_id;
+      $ids['trxn_id'] = $dao->trxn_id;
     }
     return $ids;
   }
 
+  /**
+   * Get the transaction id for the (latest) refund associated with a contribution.
+   *
+   * @param int $contributionID
+   * @return string
+   */
+  public static function getRefundTransactionTrxnID($contributionID) {
+    $ids = self::getRefundTransactionIDs($contributionID);
+    return isset($ids['trxn_id']) ? $ids['trxn_id'] : NULL;
+  }
+
+  /**
+   * Get the transaction id for the (latest) refund associated with a contribution.
+   *
+   * @param int $contributionID
+   * @return string
+   */
+  public static function getRefundTransactionIDs($contributionID) {
+    $refundStatusID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded');
+    return self::getFinancialTrxnId($contributionID, 'DESC', FALSE, " AND cft.status_id = $refundStatusID");
+  }
+
   /**
    * Given an entity_id and entity_table, check for corresponding entity_financial_trxn and financial_trxn record.
    * @todo This should be moved to separate BAO for EntityFinancialTrxn when we start adding more code for that object.
index b29113c16091a03c6177489bfc339016bf3ad778..0eb42a2545cbf3ad3578b3e4dd46cb64768bdcfc 100644 (file)
               <td class="label" style="vertical-align: top;">{$form.cancel_reason.label}</td>
               <td>{$form.cancel_reason.html}</td>
             </tr>
+            <tr id="refundTrxnID">
+              <td class="label" style="vertical-align: top;">{$form.refund_trxn_id.label}</td>
+              <td>{$form.refund_trxn_id.html}</td>
+            </tr>
           </table>
         </fieldset>
         </td>
index dce14466d8ae8d0cf362f2f00c85ca067e555ab8..edd39ae6b34d5778a3de8412ac30105ccab67404 100644 (file)
         <td>{$cancel_reason}</td>
       </tr>
     {/if}
+    {if $refund_trxn_id}
+      <tr>
+        <td class="label">{ts}Refund Transaction ID{/ts}</td>
+        <td>{$refund_trxn_id}</td>
+      </tr>
+    {/if}
   {/if}
   <tr>
     <td class="label">{ts}Payment Method{/ts}</td>