Merge pull request #10506 from seamuslee001/CRM-20253-test
[civicrm-core.git] / api / v3 / Payment.php
index f843ded7d22b674516f81874415a48a6c7e5fb95..1b96697a30a308970cd6a9dcc2f4d95dd7a58c04 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.7                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2016                                |
+ | Copyright CiviCRM LLC (c) 2004-2017                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -49,23 +49,29 @@ function civicrm_api3_payment_get($params) {
   $params['options']['limit'] = 0;
   $eft = civicrm_api3('EntityFinancialTrxn', 'get', $params);
   if (!empty($eft['values'])) {
+    $eftIds = array();
     foreach ($eft['values'] as $efts) {
+      if (empty($efts['financial_trxn_id'])) {
+        continue;
+      }
       $eftIds[] = $efts['financial_trxn_id'];
       $map[$efts['financial_trxn_id']] = $efts['entity_id'];
     }
-    $ftParams = array(
-      'id' => array('IN' => $eftIds),
-      'is_payment' => 1,
-    );
-    if ($limit) {
-      $ftParams['options']['limit'] = $limit;
-    }
-    $financialTrxn = civicrm_api3('FinancialTrxn', 'get', $ftParams);
-    foreach ($financialTrxn['values'] as &$values) {
-      $values['contribution_id'] = $map[$values['id']];
+    if (!empty($eftIds)) {
+      $ftParams = array(
+        'id' => array('IN' => $eftIds),
+        'is_payment' => 1,
+      );
+      if ($limit) {
+        $ftParams['options']['limit'] = $limit;
+      }
+      $financialTrxn = civicrm_api3('FinancialTrxn', 'get', $ftParams);
+      foreach ($financialTrxn['values'] as &$values) {
+        $values['contribution_id'] = $map[$values['id']];
+      }
     }
   }
-  return civicrm_api3_create_success(CRM_Utils_Array::value('values', $financialTrxn), $params, 'Payment', 'get');
+  return civicrm_api3_create_success(CRM_Utils_Array::value('values', $financialTrxn, array()), $params, 'Payment', 'get');
 }
 
 /**
@@ -121,58 +127,79 @@ function civicrm_api3_payment_cancel(&$params) {
  */
 function civicrm_api3_payment_create(&$params) {
   // Check if it is an update
-  if ($params['id']) {
+  if (CRM_Utils_Array::value('id', $params)) {
     $amount = $params['total_amount'];
     civicrm_api3('Payment', 'cancel', $params);
     $params['total_amount'] = $amount;
   }
   // Get contribution
   $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $params['contribution_id']));
-  if ($contribution['contribution_status'] != 'Partially paid') {
-    throw new API_Exception('Please select a contribution which has a partial payment');
+  $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name');
+  if ($contributionStatus != 'Partially paid'
+    && !($contributionStatus == 'Pending' && $contribution['is_pay_later'] == TRUE)
+  ) {
+    throw new API_Exception('Please select a contribution which has a partial or pending payment');
   }
   else {
-    $trxn = CRM_Contribute_BAO_Contribution::recordPartialPayment($contribution, $params);
-    $paid = CRM_Core_BAO_FinancialTrxn::getTotalPayments($params['contribution_id']);
-    $total = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution_id'], 'total_amount');
-    $cmp = bccomp($total, $paid, 5);
-    if ($cmp == 0 || $cmp == -1) {// If paid amount is greater or equal to total amount
-      civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id']));
+    // Check if pending contribution
+    $fullyPaidPayLater = FALSE;
+    if ($contributionStatus == 'Pending') {
+      $cmp = bccomp($contribution['total_amount'], $params['total_amount'], 5);
+      // Total payment amount is the whole amount paid against pending contribution
+      if ($cmp == 0 || $cmp == -1) {
+        civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id']));
+        // Get the trxn
+        $trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
+        $ftParams = array('id' => $trxnId['financialTrxnId']);
+        $trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray);
+        $fullyPaidPayLater = TRUE;
+      }
+      else {
+        civicrm_api3('Contribution', 'create',
+          array(
+            'id' => $contribution['id'],
+            'contribution_status_id' => 'Partially paid',
+          )
+        );
+      }
     }
-  }
-  if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) {
-    foreach ($params['line_item'] as $values) {
-      foreach ($values as $id => $amount) {
-        $p = array('id' => $id);
-        $check = CRM_Price_BAO_LineItem::retrieve($p, $defaults);
-        if (empty($check)) {
-          throw new API_Exception('Please specify a valid Line Item.');
+    if (!$fullyPaidPayLater) {
+      $trxn = CRM_Core_BAO_FinancialTrxn::getPartialPaymentTrxn($contribution, $params);
+      if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) {
+        foreach ($params['line_item'] as $values) {
+          foreach ($values as $id => $amount) {
+            $p = array('id' => $id);
+            $check = CRM_Price_BAO_LineItem::retrieve($p, $defaults);
+            if (empty($check)) {
+              throw new API_Exception('Please specify a valid Line Item.');
+            }
+            // get financial item
+            $sql = "SELECT fi.id
+              FROM civicrm_financial_item fi
+              INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item'
+              WHERE li.contribution_id = %1 AND li.id = %2";
+            $sqlParams = array(
+              1 => array($params['contribution_id'], 'Integer'),
+              2 => array($id, 'Integer'),
+            );
+            $fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams);
+            // Record Entity Financial Trxn
+            $eftParams = array(
+              'entity_table' => 'civicrm_financial_item',
+              'financial_trxn_id' => $trxn->id,
+              'amount' => $amount,
+              'entity_id' => $fid,
+            );
+            civicrm_api3('EntityFinancialTrxn', 'create', $eftParams);
+          }
         }
-        // get financial item
-        $sql = "SELECT fi.id
-          FROM civicrm_financial_item fi
-          INNER JOIN civicrm_line_item li ON li.id = fi.entity_id
-          WHERE li.contribution_id = %1 AND li.id = %2";
-        $sqlParams = array(
-          1 => array($params['contribution_id'], 'Integer'),
-          2 => array($id, 'Integer'),
-        );
-        $fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams);
-        // Record Entity Financial Trxn
-        $eftParams = array(
-          'entity_table' => 'civicrm_financial_item',
-          'financial_trxn_id' => $trxn->id,
-          'amount' => $amount,
-          'entity_id' => $fid,
-        );
-        civicrm_api3('EntityFinancialTrxn', 'create', $eftParams);
+      }
+      elseif (!empty($trxn)) {
+        // Assign the lineitems proportionally
+        CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution['total_amount']);
       }
     }
   }
-  elseif (!empty($trxn)) {
-    // Assign the lineitems proportionally
-    CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn, $contribution);
-  }
   $values = array();
   _civicrm_api3_object_to_array_unique_fields($trxn, $values[$trxn->id]);
   return civicrm_api3_create_success($values, $params, 'Payment', 'create', $trxn);