Fix test to use validateAllContributions
authoreileen <emcnaughton@wikimedia.org>
Fri, 4 Sep 2020 01:38:03 +0000 (13:38 +1200)
committereileen <emcnaughton@wikimedia.org>
Fri, 4 Sep 2020 10:18:14 +0000 (22:18 +1200)
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Financial/BAO/Order.php
tests/phpunit/CiviTest/CiviUnitTestCase.php
tests/phpunit/api/v3/ContributionPageTest.php
tests/phpunit/api/v3/ContributionTest.php

index a9a2988d4d9765bc9287b0b0fb3fad20ed2ed925..0e5750e76899bfb37ff80c38b6e44b9eb444fe1a 100644 (file)
@@ -1903,9 +1903,19 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $params['invoiceID'] = md5(uniqid(rand(), TRUE));
 
     // We want to move away from passing in amount as it is calculated by the actually-submitted params.
-    $params['amount'] = $params['amount'] ?? $form->getMainContributionAmount($params);
+    if ($form->getMainContributionAmount($params)) {
+      $params['amount'] = $form->getMainContributionAmount($params);
+    }
     $paramsProcessedForForm = $form->_params = self::getFormParams($params['id'], $params);
-    $form->_amount = $params['amount'];
+
+    $order = new CRM_Financial_BAO_Order();
+    $order->setPriceSelectionFromUnfilteredInput($params);
+    if (isset($params['amount'])) {
+      // @todo deprecate receiving amount, calculate on the form.
+      $order->setOverrideTotalAmount($params['amount']);
+    }
+    $amount = $order->getTotalAmount();
+    $form->_amount = $params['amount'] = $form->_params['amount'] = $params['amount'] ?? $amount;
     // hack these in for test support.
     $form->_fields['billing_first_name'] = 1;
     $form->_fields['billing_last_name'] = 1;
index 43fa9cd2d72a7c81950994a9eee0865686cf614e..80cf3b66ec58377f69614e35672c2e7a238f2512 100644 (file)
@@ -9,6 +9,8 @@
  +--------------------------------------------------------------------+
  */
 
+use Civi\Api4\PriceField;
+
 /**
  *
  * @package CRM
@@ -231,9 +233,15 @@ class CRM_Financial_BAO_Order {
     }
 
     foreach ($this->getPriceOptions() as $fieldID => $valueID) {
+      if (!isset($this->priceSetID)) {
+        $this->setPriceSetID(PriceField::get()->addSelect('price_set_id')->addWhere('id', '=', $fieldID)->execute()->first()['price_set_id']);
+      }
       $throwAwayArray = [];
       // @todo - still using getLine for now but better to bring it to this class & do a better job.
-      $lineItems[$valueID] = CRM_Price_BAO_PriceSet::getLine($params, $throwAwayArray, $this->getPriceSetID(), $this->getPriceFieldSpec($fieldID), $fieldID, 0)[1][$valueID];
+      $newLines = CRM_Price_BAO_PriceSet::getLine($params, $throwAwayArray, $this->getPriceSetID(), $this->getPriceFieldSpec($fieldID), $fieldID, 0)[1];
+      foreach ($newLines as $newLine) {
+        $lineItems[$newLine['price_field_value_id']] = $newLine;
+      }
     }
 
     foreach ($lineItems as &$lineItem) {
@@ -261,7 +269,7 @@ class CRM_Financial_BAO_Order {
   }
 
   /**
-   * Get the total tax amount for the order.
+   * Get the total amount for the order.
    *
    * @return float
    *
@@ -275,6 +283,21 @@ class CRM_Financial_BAO_Order {
     return $amount;
   }
 
+  /**
+   * Get the total tax amount for the order.
+   *
+   * @return float
+   *
+   * @throws \CiviCRM_API3_Exception
+   */
+  public function getTotalAmount() :float {
+    $amount = 0.0;
+    foreach ($this->getLineItems() as $lineItem) {
+      $amount += $lineItem['line_total'] ?? 0.0;
+    }
+    return $amount;
+  }
+
   /**
    * Get the tax rate for the given financial type.
    *
index 0e889a4299372bfd861459221e61ad79666f4828..bd09aec21b876651d12e92279f11465444ee7b1a 100644 (file)
@@ -3551,13 +3551,16 @@ VALUES
    * @throws \CRM_Core_Exception
    */
   protected function validateAllContributions() {
-    $contributions = $this->callAPISuccess('Contribution', 'get', [])['values'];
+    $contributions = $this->callAPISuccess('Contribution', 'get', ['return' => ['tax_amount', 'total_amount']])['values'];
     foreach ($contributions as $contribution) {
       $lineItems = $this->callAPISuccess('LineItem', 'get', ['contribution_id' => $contribution['id']])['values'];
       $total = 0;
+      $taxTotal = 0;
       foreach ($lineItems as $lineItem) {
         $total += $lineItem['line_total'];
+        $taxTotal += (float) ($lineItem['tax_amount'] ?? 0);
       }
+      $this->assertEquals($taxTotal, (float) ($contribution['tax_amount'] ?? 0));
       $this->assertEquals($total, $contribution['total_amount']);
     }
   }
index 689694a72a4660e86131ee472ac3484c94addcdd..83d2d3966fae041a4ffe6fd85683f9fae37fc796 100644 (file)
@@ -1862,7 +1862,6 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
     $submitParams = [
       'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
       'id' => (int) $this->_ids['contribution_page'],
-      'amount' => 80,
       'first_name' => 'Billy',
       'last_name' => 'Gruff',
       'email' => 'billy@goat.gruff',
@@ -1870,7 +1869,7 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
     ];
     $this->addPriceFields($submitParams);
 
-    $this->callAPISuccess('contribution_page', 'submit', $submitParams);
+    $this->callAPISuccess('ContributionPage', 'submit', $submitParams);
     $contribution = $this->callAPISuccessGetSingle('contribution', [
       'contribution_page_id' => $this->_ids['contribution_page'],
       'contribution_status_id' => 'Pending',
@@ -1988,12 +1987,12 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
     // Set quantity for our test
     $submitParams['price_' . $priceFieldId] = 110;
 
-    // contribution_page submit requires amount and tax_amount - and that's ok we're not testing that - we're testing at the LineItem level
-    $submitParams['amount'] = $this->formatMoneyInput(180 * 16.95 + 110 * 2.95);
     // This is the correct Tax Amount - use it later to compare to what the CiviCRM Core came up with at the LineItem level
     $submitParams['tax_amount'] = (180 * 16.95 * 0.10 + 110 * 2.95 * 0.10);
 
-    $this->callAPISuccess('contribution_page', 'submit', $submitParams);
+    $this->callAPISuccess('ContributionPage', 'submit', $submitParams);
+    $this->validateAllContributions();
+
     $contribution = $this->callAPISuccessGetSingle('contribution', [
       'contribution_page_id' => $this->_ids['contribution_page'],
     ]);
@@ -2011,13 +2010,8 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
     ]);
 
     $finalContribution = $this->callAPISuccess('Contribution', 'getsingle', ['id' => $contribution['id'], 'return' => ['tax_amount', 'total_amount']]);
-
     $this->assertEquals($lineItem1['line_total'] + $lineItem2['line_total'], round(180 * 16.95 + 110 * 2.95, 2), 'Line Item Total is incorrect.');
-    $this->assertEquals($lineItem1['line_total'] + $lineItem2['line_total'], $finalContribution['total_amount'], 'Contribution total should match line item totals');
-
     $this->assertEquals(round($lineItem1['tax_amount'] + $lineItem2['tax_amount'], 2), round(180 * 16.95 * 0.10 + 110 * 2.95 * 0.10, 2), 'Wrong Sales Tax Amount is calculated and stored.');
-    $this->assertEquals(round($lineItem1['tax_amount'] + $lineItem2['tax_amount'], 2), $finalContribution['tax_amount'], 'Sales Tax Amount on Contribution does not match sum of Sales Tax Amount across the Line Items.');
-
   }
 
   /**
index 503cba4b9a1401089ce726544ab7d238dd79fba1..1781250d1dd34ed9c860d73fd850ef3a9e7f5920 100644 (file)
@@ -2098,7 +2098,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
   /**
    * Test to ensure mail is sent on chosing pay later
    */
-  public function testpayLater() {
+  public function testPayLater() {
     $mut = new CiviMailUtils($this, TRUE);
     $this->swapMessageTemplateForTestTemplate();
     $this->createLoggedInUser();
@@ -2140,7 +2140,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
       'description' => 'Online Contribution: Help Support CiviCRM!',
       'price_set_id' => $priceSet['id'],
     ];
-    $this->callAPISuccess('contribution_page', 'submit', $params);
+    $this->callAPISuccess('ContributionPage', 'submit', $params);
 
     $mut->checkMailLog([
       'is_pay_later:::1',