Add helper functions to contribution page
authorEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 20 Nov 2023 12:13:59 +0000 (01:13 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 20 Nov 2023 12:13:59 +0000 (01:13 +1300)
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Contribute/Form/ContributionBase.php
CRM/Financial/BAO/Order.php

index d3172f995fd6452a3fbd1f46366d6293c080f4b6..343cd1029aab0ac4691c809cc3002c82b72f5fee 100644 (file)
@@ -1900,16 +1900,16 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
 
     $paramsProcessedForForm = $form->_params = self::getFormParams($params['id'], $params);
 
-    $order = new CRM_Financial_BAO_Order();
-    $order->setPriceSetIDByContributionPageID($params['id']);
-    $order->setPriceSelectionFromUnfilteredInput($params);
+    $form->order = new CRM_Financial_BAO_Order();
+    $form->order->setPriceSetIDByContributionPageID($params['id']);
+    $form->order->setPriceSelectionFromUnfilteredInput($params);
     if (isset($params['amount']) && !$form->isSeparateMembershipPayment()) {
       // @todo deprecate receiving amount, calculate on the form.
-      $order->setOverrideTotalAmount((float) $params['amount']);
+      $form->order->setOverrideTotalAmount((float) $params['amount']);
     }
-    $amount = $order->getTotalAmount();
+    $amount = $form->order->getTotalAmount();
     if ($form->isSeparateMembershipPayment()) {
-      $amount -= $order->getMembershipTotalAmount();
+      $amount -= $form->order->getMembershipTotalAmount();
     }
     $form->_amount = $params['amount'] = $form->_params['amount'] = $amount;
     // hack these in for test support.
@@ -1948,9 +1948,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     }
     $priceFields = $priceFields[$priceSetID]['fields'];
 
-    $form->_lineItem = [$priceSetID => $order->getLineItems()];
+    $form->_lineItem = [$priceSetID => $form->order->getLineItems()];
     $membershipPriceFieldIDs = [];
-    foreach ($order->getLineItems() as $lineItem) {
+    foreach ($form->order->getLineItems() as $lineItem) {
       if (!empty($lineItem['membership_type_id'])) {
         $form->set('useForMember', 1);
         $form->_useForMember = 1;
index 00f2f9c12cf41d418dc58c9c0c84a5feff1b3d5e..cef3b2fe24eea9486615420a13f90bedc5c3d0d3 100644 (file)
@@ -365,10 +365,7 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
     // In tests price set id is not always set - it is unclear if this is just
     // poor test set up or it is possible in 'the real world'
     if ($this->getPriceSetID()) {
-      $this->order = new CRM_Financial_BAO_Order();
-      $this->order->setPriceSetID($this->getPriceSetID());
-      $this->order->setIsExcludeExpiredFields(TRUE);
-      $this->order->setPriceSelectionFromUnfilteredInput($this->getSubmittedValues());
+      $this->initializeOrder();
     }
     else {
       CRM_Core_Error::deprecatedFunctionWarning('forms require a price set ID');
@@ -530,6 +527,108 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
     }
   }
 
+  /**
+   * Set the selected line items.
+   *
+   * This returns all selected line items, even if they will
+   * be split to a secondary contribution.
+   *
+   * @api Supported for external use.
+   *
+   * @return array
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function getLineItems(): array {
+    return $this->order->getLineItems();
+  }
+
+  /**
+   * Set the selected line items.
+   *
+   * This returns all selected line items, even if they will
+   * be split to a secondary contribution.
+   *
+   * @api Supported for external use.
+   */
+  public function setLineItems($lineItems): void {
+    $this->order->setLineItems($lineItems);
+    $this->set('_lineItem', $lineItems);
+  }
+
+  /**
+   * Set the selected line items.
+   *
+   * @internal
+   *
+   * @return array
+   *
+   * @throws \CRM_Core_Exception
+   */
+  protected function getMainContributionLineItems(): array {
+    $membershipLineItems = $this->getSecondaryMembershipContributionLineItems();
+    $allLineItems = $this->getOrder()->getLineItems();
+    if (!$membershipLineItems || $allLineItems === $membershipLineItems) {
+      return $allLineItems;
+    }
+    $mainContributionLineItems = [];
+    foreach ($allLineItems as $index => $lineItem) {
+      if (empty($lineItem['membership_type_id'])) {
+        $mainContributionLineItems[$index] = $lineItem;
+      }
+    }
+    return $mainContributionLineItems;
+  }
+
+  /**
+   * Set the line items for the secondary membership contribution.
+   *
+   * Return false if the page is not configured for separate contributions,
+   * or if only the membership or the contribution has been selected.
+   *
+   * @internal
+   *
+   * @return array|false
+   *
+   * @throws \CRM_Core_Exception
+   */
+  protected function getSecondaryMembershipContributionLineItems() {
+    if (!$this->isSeparateMembershipPayment()) {
+      return FALSE;
+    }
+    $lineItems = [];
+    foreach ($this->getLineItems() as $index => $lineItem) {
+      if (!empty($lineItem['membership_type_id'])) {
+        $lineItems[$index] = $lineItem;
+      }
+    }
+    if (empty($lineItems) || count($lineItems) === $this->getLineItems()) {
+      return FALSE;
+    }
+    return $lineItems;
+  }
+
+  /**
+   * Get membership line items.
+   *
+   * Get all line items relating to membership, regardless of primary or secondary membership.
+   *
+   * @internal
+   *
+   * @return array
+   *
+   * @throws \CRM_Core_Exception
+   */
+  protected function getMembershipLineItems(): array {
+    $lineItems = [];
+    foreach ($this->getLineItems() as $index => $lineItem) {
+      if (!empty($lineItem['membership_type_id'])) {
+        $lineItems[$index] = $lineItem;
+      }
+    }
+    return $lineItems;
+  }
+
   /**
    * Initiate price set such that various non-BAO things are set on the form.
    *
@@ -1298,4 +1397,25 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
     return NULL;
   }
 
+  protected function getOrder(): CRM_Financial_BAO_Order {
+    if (!$this->order) {
+      $this->initializeOrder();
+    }
+    return $this->order;
+  }
+
+  protected function initializeOrder(): void {
+    $this->order = new CRM_Financial_BAO_Order();
+    $this->order->setPriceSetID($this->getPriceSetID());
+    $this->order->setIsExcludeExpiredFields(TRUE);
+    if ($this->get('lineItem')) {
+      $this->order->setLineItems($this->get('lineItem')[$this->getPriceSetID()]);
+    }
+    if ($this->getExistingContributionID()) {
+      $this->order->setTemplateContributionID($this->getExistingContributionID());
+    }
+    $this->order->setPriceSelectionFromUnfilteredInput($this->getSubmittedValues());
+    $this->order->setForm($this);
+  }
+
 }
index ca74b7d44c9405b197d9133ce1fb245c8303c7e0..7bc308338e0b5676468b2046bb46f46970330226 100644 (file)
@@ -1121,6 +1121,18 @@ class CRM_Financial_BAO_Order {
     $this->lineItems[$index][$name] = $value;
   }
 
+  /**
+   * Set the line item array.
+   *
+   * This is mostly useful when they have been calculated & stored
+   * on the form & we want to rebuild the line item object.
+   *
+   * @param array $lineItems
+   */
+  public function setLineItems(array $lineItems): void {
+    $this->lineItems = $lineItems;
+  }
+
   /**
    * @param int|string $index
    *