create api test for contributions for sales tax
[civicrm-core.git] / CRM / Contribute / BAO / Contribution.php
index e92faa48a49bb6e3c21198610002c377bdd066ef..876a43c1757d99484fc1f16a39644d82d9b37ea4 100644 (file)
@@ -149,7 +149,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
 
     // contribution status is missing, choose Completed as default status
     // do this for create mode only
-    if (empty($ids['contribution']) && empty($params['contribution_status_id'])) {
+    if (!$contributionID && empty($params['contribution_status_id'])) {
       $params['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name');
     }
     $setPrevContribution = TRUE;
@@ -238,6 +238,31 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
     return NULL;
   }
 
+  /**
+   * Get the number of terms for this contribution for a given membership type
+   * based on querying the line item table and relevant price field values
+   * Note that any one contribution should only be able to have one line item relating to a particular membership
+   * type
+   * @param int $membershipTypeID
+   *
+   * @return int
+   */
+  public function getNumTermsByContributionAndMembershipType($membershipTypeID) {
+    if (!is_numeric($membershipTypeID)) {
+      //precautionary measure - this is being introduced to a mature release hence adding extra checks that
+      // might be removed later
+      return 1;
+    }
+    $numTerms = CRM_Core_DAO::singleValueQuery("
+      SELECT membership_num_terms FROM civicrm_line_item li
+      LEFT JOIN civicrm_price_field_value v ON li.price_field_value_id = v.id
+      WHERE contribution_id = %1 AND membership_type_id = %2",
+      array(1 => array($this->id, 'Integer') , 2 => array($membershipTypeID, 'Integer'))
+    );
+    // default of 1 is precautionary
+    return empty($numTerms) ? 1 : $numTerms;
+  }
+
   /**
    * takes an associative array and creates a contribution object
    *
@@ -2302,6 +2327,14 @@ WHERE  contribution_id = %1 ";
    * function & breaking it down into manageable chunks. Eventually it will be refactored into something else
    * Note we send directly from this function in some cases because it is only partly refactored
    * Don't call this function directly as the signature will change
+   *
+   * @param $values
+   * @param $input
+   * @param $template CRM_Core_SMARTY
+   * @param bool $recur
+   * @param bool $returnMessageText
+   *
+   * @return mixed
    */
   function _assignMessageVariablesToTemplate(&$values, $input, &$template, $recur = FALSE, $returnMessageText = True) {
     $template->assign('first_name', $this->_relatedObjects['contact']->first_name);
@@ -2310,7 +2343,7 @@ WHERE  contribution_id = %1 ";
     if (!empty($values['lineItem']) && !empty($this->_relatedObjects['membership'])) {
       $template->assign('useForMember', true);
     }
-    //assign honor infomation to receiptmessage
+    //assign honor information to receipt message
     $softRecord = CRM_Contribute_BAO_ContributionSoft::getSoftContribution($this->id);
 
     if (isset($softRecord['soft_credit'])) {
@@ -2543,16 +2576,15 @@ WHERE  contribution_id = %1 ";
    * @param array $params contribution object, line item array and params for trxn
    *
    *
-   * @param null $financialTrxnVals
+   * @param array $financialTrxnValues
    *
    * @return null|object
    * @access public
    * @static
    */
-  static function recordFinancialAccounts(&$params, $financialTrxnVals = NULL) {
-    $skipRecords = $update = FALSE;
-    // in few scenarios we require the trxn record details which has got created
-    $return = NULL;
+  static function recordFinancialAccounts(&$params, $financialTrxnValues = NULL) {
+    $skipRecords = $update = $return = FALSE;
+
     $additionalParticipantId = array();
     $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
 
@@ -2561,6 +2593,12 @@ WHERE  contribution_id = %1 ";
       $entityTable = 'civicrm_participant';
       $additionalParticipantId = CRM_Event_BAO_Participant::getAdditionalParticipantIds($entityId);
     }
+    elseif (!empty($params['membership_id'])) {
+      //so far $params['membership_id'] should only be set coming in from membershipBAO::create so the situation where multiple memberships
+      // are created off one contribution should be handled elsewhere
+      $entityId = $params['membership_id'];
+      $entityTable = 'civicrm_membership';
+    }
     else {
       $entityId = $params['contribution']->id;
       $entityTable = 'civicrm_contribution';
@@ -2668,8 +2706,8 @@ WHERE  contribution_id = %1 ";
       }
 
       // consider external values passed for recording transaction entry
-      if (!empty($financialTrxnVals)) {
-        $trxnParams = array_merge($trxnParams, $financialTrxnVals);
+      if (!empty($financialTrxnValues)) {
+        $trxnParams = array_merge($trxnParams, $financialTrxnValues);
       }
 
       $params['trxnParams'] = $trxnParams;
@@ -2926,6 +2964,7 @@ WHERE  contribution_id = %1 ";
           if ($params['contribution']->currency) {
             $currency = $params['contribution']->currency;
           }
+          $diff = 1;
           if (!empty($params['is_quick_config'])) {
             $amount = $itemAmount;
             if (!$amount) {
@@ -2933,7 +2972,6 @@ WHERE  contribution_id = %1 ";
             }
           }
           else {
-            $diff = 1;
             if ($context == 'changeFinancialType' || $params['contribution']->contribution_status_id == array_search('Cancelled', $contributionStatus)
               || $params['contribution']->contribution_status_id == array_search('Refunded', $contributionStatus)) {
              $diff = -1;
@@ -2953,6 +2991,17 @@ WHERE  contribution_id = %1 ";
             'entity_id' => $fieldValues['id']
           );
           CRM_Financial_BAO_FinancialItem::create($itemParams, NULL, $trxnIds);
+
+          if ($fieldValues['tax_amount']) {
+            $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
+            $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
+            $itemParams['amount'] = $diff * $fieldValues['tax_amount'];
+            $itemParams['description'] = $taxTerm;
+            if ($fieldValues['financial_type_id']) {
+              $itemParams['financial_account_id'] = self::getFinancialAccountId($fieldValues['financial_type_id']);
+            }
+            CRM_Financial_BAO_FinancialItem::create($itemParams, NULL, $trxnIds);
+          }
         }
       }
     }
@@ -3368,4 +3417,99 @@ WHERE con.id = {$contributionId}
     }
     return $info;
   }
+
+  /**
+   * Function to get financial account id has 'Sales Tax Account is'
+   * account relationship with financial type
+   *
+   * @param $financialTypeId
+   *
+   * @return FinancialAccountId
+   */
+  static function getFinancialAccountId($financialTypeId) {
+    $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' "));
+    $searchParams = array(
+      'entity_table' => 'civicrm_financial_type',
+      'entity_id' => $financialTypeId,
+      'account_relationship' => $accountRel,
+    );
+    $result = array();
+    CRM_Financial_BAO_FinancialTypeAccount::retrieve( $searchParams, $result );
+
+    return CRM_Utils_Array::value( 'financial_account_id', $result );
+  }
+
+  function checkTaxAmount($params, $isLineItem = FALSE) {
+    $taxRates = CRM_Core_PseudoConstant::getTaxRates();
+
+    // Update contribution
+    if (!empty($params['id'])) {
+      $id = $params['id'];
+      $values = $ids = array();
+      $contrbutionParams = array('id' => $id);
+      $prevContributionValue = CRM_Contribute_BAO_Contribution::getValues($contrbutionParams, $values, $ids);
+
+      // To assign pervious finantial type on update of contribution
+     if (!isset($params['financial_type_id'])) {
+        $params['financial_type_id'] = $prevContributionValue->financial_type_id;
+      }
+      else if (isset($params['financial_type_id']) && !array_key_exists($params['financial_type_id'], $taxRates)) {
+        // Assisn tax Amount on update of contrbution
+        if (!empty($prevContributionValue->tax_amount)) {
+          $params['tax_amount'] = 'null';
+          CRM_Price_BAO_LineItem::getLineItemArray($params, array($params['id']));
+          foreach ($params['line_item'] as $setID => $priceField) {
+            foreach ($priceField as $priceFieldID => $priceFieldValue) {
+              $params['line_item'][$setID][$priceFieldID]['tax_amount'] = $params['tax_amount'];
+            }
+          }
+        }
+      }
+    }
+
+    // New Contrbution and update of contribution with tax rate financial type
+    if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && 
+      empty($params['skipLineItem']) && !$isLineItem)
+      {
+        $taxRateParams = $taxRates[$params['financial_type_id']];
+        $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['total_amount'], $taxRateParams);
+        $params['tax_amount'] = round($taxAmount['tax_amount'], 2);
+
+        // Get Line Item on update of contribution
+        if (isset($params['id'])) {
+          CRM_Price_BAO_LineItem::getLineItemArray($params, array($params['id']));
+        }
+        else {
+          CRM_Price_BAO_LineItem::getLineItemArray($params);
+        }
+        foreach ($params['line_item'] as $setID => $priceField) {
+          foreach ($priceField as $priceFieldID => $priceFieldValue) {
+           $params['line_item'][$setID][$priceFieldID]['tax_amount'] = $params['tax_amount'];
+          }
+        }
+        $params['total_amount'] = $params['total_amount'] + $params['tax_amount'];
+      } 
+    else if (isset($params['api.line_item.create'])) {
+      // Update total amount of contribution using lineItem 
+      $taxAmountArray = array();
+      foreach ($params['api.line_item.create'] as $key => $value) {
+        if (isset($value['financial_type_id']) && array_key_exists($value['financial_type_id'], $taxRates)) {
+         $taxRate = $taxRates[$value['financial_type_id']];
+          $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($value['line_total'], $taxRate);                   
+          $taxAmountArray[] = round($taxAmount['tax_amount'], 2);
+        }
+      }
+      $params['tax_amount'] = array_sum($taxAmountArray);
+      $params['total_amount'] = $params['total_amount'] + $params['tax_amount'];  
+    }
+    else {
+      // update line item of contrbution
+      if (isset($params['financial_type_id']) && array_key_exists($params['financial_type_id'], $taxRates) && $isLineItem) {
+        $taxRate = $taxRates[$params['financial_type_id']];
+        $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($params['line_total'], $taxRate);
+        $params['tax_amount'] = round($taxAmount['tax_amount'], 2);
+      }
+    }
+    return $params;
+  }
 }