Ejegg has submitted this change and it was merged.

Change subject: CRM-17951 ( merged into  4.7) add support for Chargeback 
contribution status and having an account relationship for refunds.
......................................................................


CRM-17951 ( merged into  4.7) add support for Chargeback contribution status 
and having an account relationship for refunds.

The support covers the relationship 'falling back' to current behaviour if a 
Contra/Credit Revenue Account is
entry is not configured for the financial type and adds support for Chargeback 
as a type.

This changes are now in 4.7 although this implementation is slightly different 
as the Civi::statics class is in 4.7 & not 4.6 so it just justs a static var in 
the function

Bug: T124979
Change-Id: I6956f8266f41b36460f1312fc8c4fb647d2e2a19
---
M CRM/Contribute/BAO/Contribution.php
M CRM/Financial/BAO/FinancialAccount.php
2 files changed, 104 insertions(+), 20 deletions(-)

Approvals:
  Ejegg: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/CRM/Contribute/BAO/Contribution.php 
b/CRM/Contribute/BAO/Contribution.php
index 7b23c01..f0bb79c 100644
--- a/CRM/Contribute/BAO/Contribution.php
+++ b/CRM/Contribute/BAO/Contribution.php
@@ -138,7 +138,7 @@
     //if contribution is created with cancelled or refunded status, add credit 
note id
     if (!empty($params['contribution_status_id'])) {
       $contributionStatus = 
CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
-
+      // @todo - should we include Chargeback? If so use 
self::isContributionStatusNegative($params['contribution_status_id'])
       if (($params['contribution_status_id'] == array_search('Refunded', 
$contributionStatus)
           || $params['contribution_status_id'] == array_search('Cancelled', 
$contributionStatus))
       ) {
@@ -2808,12 +2808,14 @@
     ) {
       $skipRecords = TRUE;
       $pendingStatus = array(
-        array_search('Pending', $contributionStatuses),
-        array_search('In Progress', $contributionStatuses),
+        'Pending',
+        'In Progress',
       );
-      if (in_array(CRM_Utils_Array::value('contribution_status_id', $params), 
$pendingStatus)) {
-        $relationTypeId = 
key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, 
" AND v.name LIKE 'Accounts Receivable Account is' "));
-        $params['to_financial_account_id'] = 
CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'],
 $relationTypeId);
+      if (in_array($contributionStatus, $pendingStatus)) {
+        $params['to_financial_account_id'] = 
CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(
+          $params['financial_type_id'],
+          'Accounts Receivable Account is'
+        );
       }
       elseif (!empty($params['payment_processor'])) {
         $params['to_financial_account_id'] = 
CRM_Financial_BAO_FinancialTypeAccount::getFinancialAccount($params['payment_processor'],
 'civicrm_payment_processor', 'financial_account_id');
@@ -2847,7 +2849,7 @@
         'check_number' => CRM_Utils_Array::value('check_number', $params),
       );
 
-      if ($contributionStatus == 'Refunded') {
+      if ($contributionStatus == 'Refunded' || $contributionStatus == 
'Chargeback') {
         $trxnParams['trxn_date'] = 
!empty($params['contribution']->cancel_date) ? 
$params['contribution']->cancel_date : date('YmdHis');
         if (isset($params['refund_trxn_id'])) {
           // CRM-17751 allow a separate trxn_id for the refund to be passed in 
via api & form.
@@ -3085,8 +3087,7 @@
       //get all the statuses
       $contributionStatus = 
CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
       if ($previousContributionStatus == 'Completed'
-        && ($params['contribution']->contribution_status_id == 
array_search('Refunded', $contributionStatus)
-          || $params['contribution']->contribution_status_id == 
array_search('Cancelled', $contributionStatus))
+        && 
(self::isContributionStatusNegative($params['contribution']->contribution_status_id))
       ) {
         $params['trxnParams']['total_amount'] = -$params['total_amount'];
         if (empty($params['contribution']->creditnote_id) || 
$params['contribution']->creditnote_id == "null") {
@@ -3177,17 +3178,14 @@
       foreach ($params['line_item'] as $fieldId => $fields) {
         foreach ($fields as $fieldValueId => $fieldValues) {
           $prevParams['entity_id'] = $fieldValues['id'];
-          $prevfinancialItem = 
CRM_Financial_BAO_FinancialItem::retrieve($prevParams, 
CRM_Core_DAO::$_nullArray);
+          $prevFinancialItem = 
CRM_Financial_BAO_FinancialItem::retrieve($prevParams, 
CRM_Core_DAO::$_nullArray);
 
           $receiveDate = 
CRM_Utils_Date::isoToMysql($params['prevContribution']->receive_date);
           if ($params['contribution']->receive_date) {
             $receiveDate = 
CRM_Utils_Date::isoToMysql($params['contribution']->receive_date);
           }
 
-          $financialAccount = $prevfinancialItem->financial_account_id;
-          if (!empty($params['financial_account_id'])) {
-            $financialAccount = $params['financial_account_id'];
-          }
+          $financialAccount = 
self::getFinancialAccountForStatusChangeTrxn($params, $prevFinancialItem);
 
           $currency = $params['prevContribution']->currency;
           if ($params['contribution']->currency) {
@@ -3201,9 +3199,7 @@
             }
           }
           else {
-            if ($context == 'changeFinancialType' || 
$params['contribution']->contribution_status_id == array_search('Cancelled', 
$contributionStatus)
-              || $params['contribution']->contribution_status_id == 
array_search('Refunded', $contributionStatus)
-            ) {
+            if ($context == 'changeFinancialType' || 
self::isContributionStatusNegative($params['contribution']->contribution_status_id))
 {
               $diff = -1;
             }
             $amount = $diff * $fieldValues['line_total'];
@@ -3214,8 +3210,8 @@
             'contact_id' => $params['prevContribution']->contact_id,
             'currency' => $currency,
             'amount' => $amount,
-            'description' => $prevfinancialItem->description,
-            'status_id' => $prevfinancialItem->status_id,
+            'description' => $prevFinancialItem->description,
+            'status_id' => $prevFinancialItem->status_id,
             'financial_account_id' => $financialAccount,
             'entity_table' => 'civicrm_line_item',
             'entity_id' => $fieldValues['id'],
@@ -3246,6 +3242,20 @@
   }
 
   /**
+   * Is this contribution status a reversal.
+   *
+   * If so we would expect to record a negative value in the financial_trxn 
table.
+   *
+   * @param int $status_id
+   *
+   * @return bool
+   */
+  public static function isContributionStatusNegative($status_id) {
+    $reversalStatuses = array('Cancelled', 'Chargeback', 'Refunded');
+    return 
in_array(CRM_Contribute_PseudoConstant::contributionStatus($status_id, 'name'), 
$reversalStatuses);
+  }
+
+  /**
    * Check status validation on update of a contribution.
    *
    * @param array $values
@@ -3269,7 +3279,7 @@
     $contributionStatuses = 
CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     $checkStatus = array(
       'Cancelled' => array('Completed', 'Refunded'),
-      'Completed' => array('Cancelled', 'Refunded'),
+      'Completed' => array('Cancelled', 'Refunded', 'Chargeback'),
       'Pending' => array('Cancelled', 'Completed', 'Failed'),
       'In Progress' => array('Cancelled', 'Completed', 'Failed'),
       'Refunded' => array('Cancelled', 'Completed'),
@@ -3864,4 +3874,32 @@
     return $creditNoteId;
   }
 
+  /**
+   * Get the financial account for the item associated with the new 
transaction.
+   *
+   * @param array $params
+   * @param CRM_Financial_BAO_FinancialItem $prevFinancialItem
+   *
+   * @return int
+   */
+  public static function getFinancialAccountForStatusChangeTrxn($params, 
$prevFinancialItem) {
+
+    if (!empty($params['financial_account_id'])) {
+      return $params['financial_account_id'];
+    }
+    $contributionStatus = 
CRM_Contribute_PseudoConstant::contributionStatus($params['contribution_status_id'],
 'name');
+    $preferredAccountsRelationships = array(
+      'Refunded' => 'Credit/Contra Revenue Account is',
+      'Chargeback' => 'Chargeback Account is',
+    );
+    if (in_array($contributionStatus, 
array_keys($preferredAccountsRelationships))) {
+      $financialTypeID = !empty($params['financial_type_id']) ? 
$params['financial_type_id'] : $params['prevContribution']->financial_type_id;
+      return 
CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(
+        $financialTypeID,
+        $preferredAccountsRelationships[$contributionStatus]
+      );
+    }
+    return $prevFinancialItem->financial_account_id;
+  }
+
 }
diff --git a/CRM/Financial/BAO/FinancialAccount.php 
b/CRM/Financial/BAO/FinancialAccount.php
index 72c29b0..163dec8 100644
--- a/CRM/Financial/BAO/FinancialAccount.php
+++ b/CRM/Financial/BAO/FinancialAccount.php
@@ -203,4 +203,50 @@
     return CRM_Core_DAO::singleValueQuery($query, $params);
   }
 
+  /**
+   * Get the Financial Account for a Financial Type Relationship Combo.
+   *
+   * Note that some relationships are optionally configured - so far
+   * Chargeback and Credit / Contra. Since these are the only 2 currently 
Income
+   * is an appropriate fallback. In future it might make sense to extend the 
logic.
+   *
+   * Note that we avoid the CRM_Core_PseudoConstant function as it stores one
+   * account per financial type and is unreliable.
+   *
+   * @param int $financialTypeID
+   *
+   * @param string $relationshipType
+   *
+   * @return int
+   */
+  public static function 
getFinancialAccountForFinancialTypeByRelationship($financialTypeID, 
$relationshipType) {
+    $relationTypeId = 
key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, 
" AND v.name LIKE '{$relationshipType}' "));
+    static $accounts = array();
+    if (!isset($accounts[$financialTypeID][$relationTypeId])) {
+      $accounts = civicrm_api3('EntityFinancialAccount', 'get', array(
+        'entity_id' => $financialTypeID,
+        'entity_table' => 'civicrm_financial_type',
+      ));
+
+      foreach ($accounts['values'] as $account) {
+        $accounts[$financialTypeID][$account['account_relationship']] = 
$account['financial_account_id'];
+      }
+
+      $accountRelationships = 
CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL);
+
+      $incomeAccountRelationshipID = array_search('Income Account is', 
$accountRelationships);
+      $incomeAccountFinancialAccountID = 
$accounts[$financialTypeID][$incomeAccountRelationshipID];
+
+      foreach (array('Chargeback Account is', 'Credit/Contra Revenue Account 
is') as $optionalAccountRelationship) {
+
+        $accountRelationshipID = array_search($optionalAccountRelationship, 
$accountRelationships);
+        if (empty($accounts[$financialTypeID][$accountRelationshipID])) {
+          $accounts[$financialTypeID][$accountRelationshipID] = 
$incomeAccountFinancialAccountID;
+        }
+      }
+
+    }
+    return $accounts[$financialTypeID][$relationTypeId];
+  }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/268459
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I6956f8266f41b36460f1312fc8c4fb647d2e2a19
Gerrit-PatchSet: 4
Gerrit-Project: wikimedia/fundraising/crm/civicrm
Gerrit-Branch: master
Gerrit-Owner: Eileen <[email protected]>
Gerrit-Reviewer: Awight <[email protected]>
Gerrit-Reviewer: Eileen <[email protected]>
Gerrit-Reviewer: Ejegg <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to