Rationalise selectedPaymentFields.
authoreileen <emcnaughton@wikimedia.org>
Mon, 23 Jul 2018 10:01:21 +0000 (22:01 +1200)
committereileen <emcnaughton@wikimedia.org>
Tue, 24 Jul 2018 20:16:53 +0000 (08:16 +1200)
The selected payments field variable is primarily used when exporting participants
with contributions. This gets the definition of it out of the returnProperties definition
and calculates it more sensibly.

CRM/Export/BAO/Export.php
CRM/Export/BAO/ExportProcessor.php
tests/phpunit/CRM/Export/BAO/ExportTest.php

index 8822076944f387cdaaf4a7e0ae78e6eff8cfdfbc..1c042f6f888632be114600745bf1f144abbaa3b2 100644 (file)
@@ -246,9 +246,6 @@ class CRM_Export_BAO_Export {
 
     $processor = new CRM_Export_BAO_ExportProcessor($exportMode, $fields, $queryOperator);
     $returnProperties = array();
-    $selectedPaymentFields = FALSE;
-    // @todo - this variable is overwritten later - it should be wholly definable in the processor fn.
-    $paymentTableId = $processor->getPaymentTableID();
 
     $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
     // Warning - this imProviders var is used in a somewhat fragile way - don't rename it
@@ -292,14 +289,6 @@ class CRM_Export_BAO_Export {
           if ($fieldName == 'event_id') {
             $returnProperties['event_id'] = 1;
           }
-          elseif (
-            $exportMode == CRM_Export_Form_Select::EVENT_EXPORT &&
-            array_key_exists($fieldName, self::componentPaymentFields())
-          ) {
-            $selectedPaymentFields = TRUE;
-            $paymentTableId = 'participant_id';
-            $returnProperties[$fieldName] = 1;
-          }
           else {
             $returnProperties[$fieldName] = 1;
           }
@@ -313,6 +302,9 @@ class CRM_Export_BAO_Export {
     else {
       $returnProperties = $processor->getDefaultReturnProperties();
     }
+    // @todo - we are working towards this being entirely a property of the processor
+    $processor->setReturnProperties($returnProperties);
+    $paymentTableId = $processor->getPaymentTableID();
 
     if ($mergeSameAddress) {
       //make sure the addressee fields are selected
@@ -463,14 +455,14 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
     $addPaymentHeader = FALSE;
 
     $paymentDetails = array();
-    if ($processor->isExportPaymentFields() || $selectedPaymentFields) {
+    if ($processor->isExportPaymentFields()) {
 
       // get payment related in for event and members
       $paymentDetails = CRM_Contribute_BAO_Contribution::getContributionDetails($exportMode, $ids);
       //get all payment headers.
       // If we haven't selected specific payment fields, load in all the
       // payment headers.
-      if (!$selectedPaymentFields) {
+      if (!$processor->isExportSpecifiedPaymentFields()) {
         $paymentHeaders = self::componentPaymentFields();
         if (!empty($paymentDetails)) {
           $addPaymentHeader = TRUE;
@@ -498,7 +490,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
     // for CRM-3157 purposes
     $i18n = CRM_Core_I18n::singleton();
 
-    list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor, $relationQuery, $selectedPaymentFields);
+    list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor, $relationQuery);
 
     $limitReached = FALSE;
     while (!$limitReached) {
@@ -549,7 +541,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
             self::fetchRelationshipDetails($relDAO, $value, $field, $row);
           }
           else {
-            $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId);
+            $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor);
           }
         }
 
@@ -574,7 +566,7 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c
         // data will already be in $row. Otherwise, add payment related
         // information, if appropriate.
         if ($addPaymentHeader) {
-          if (!$selectedPaymentFields) {
+          if (!$processor->isExportSpecifiedPaymentFields()) {
             if ($processor->isExportPaymentFields()) {
               $paymentData = CRM_Utils_Array::value($row[$paymentTableId], $paymentDetails);
               if (!is_array($paymentData) || empty($paymentData)) {
@@ -1528,10 +1520,10 @@ WHERE  {$whereClause}";
    * @param array $phoneTypes
    * @param array $imProviders
    * @param string $relationQuery
-   * @param array $selectedPaymentFields
+   *
    * @return array
    */
-  public static function setHeaderRows($field, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields) {
+  public static function setHeaderRows($field, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery) {
 
     $queryFields = $processor->getQueryFields();
     // Split campaign into 2 fields for id and title
@@ -1610,7 +1602,7 @@ WHERE  {$whereClause}";
       }
       self::manipulateHeaderRows($headerRows);
     }
-    elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) {
+    elseif ($processor->isExportPaymentFields() && array_key_exists($field, self::componentPaymentFields())) {
       $headerRows[] = CRM_Utils_Array::value($field, self::componentPaymentFields());
     }
     else {
@@ -1634,7 +1626,7 @@ WHERE  {$whereClause}";
    * @param array $returnProperties
    * @param \CRM_Export_BAO_ExportProcessor $processor
    * @param string $relationQuery
-   * @param array $selectedPaymentFields
+   *
    * @return array
    *   - outputColumns Array of columns to be exported. The values don't matter but the key must match the
    *   alias for the field generated by BAO_Query object.
@@ -1651,7 +1643,7 @@ WHERE  {$whereClause}";
    *    - b) this code is old & outdated. Submit your answers to circular bin or better
    *       yet find a way to comment them for posterity.
    */
-  public static function getExportStructureArrays($returnProperties, $processor, $relationQuery, $selectedPaymentFields) {
+  public static function getExportStructureArrays($returnProperties, $processor, $relationQuery) {
     $metadata = $headerRows = $outputColumns = $sqlColumns = array();
     $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
     $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id');
@@ -1660,7 +1652,7 @@ WHERE  {$whereClause}";
     foreach ($returnProperties as $key => $value) {
       if ($key != 'location' || !is_array($value)) {
         $outputColumns[$key] = $value;
-        list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields);
+        list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery);
       }
       else {
         foreach ($value as $locationType => $locationFields) {
@@ -1685,7 +1677,7 @@ WHERE  {$whereClause}";
               $metadata[$daoFieldName]['pseudoconstant']['var'] = 'imProviders';
             }
             self::sqlColumnDefn($processor, $sqlColumns, $outputFieldName);
-            list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields);
+            list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery);
             if ($actualDBFieldName == 'country' || $actualDBFieldName == 'world_region') {
               $metadata[$daoFieldName] = array('context' => 'country');
             }
@@ -1920,12 +1912,13 @@ WHERE  {$whereClause}";
    * @param $fieldValue
    * @param $i18n
    * @param $metadata
-   * @param $selectedPaymentFields
    * @param $paymentDetails
-   * @param string $paymentTableId
+   *
+   * @param \CRM_Export_BAO_ExportProcessor $processor
+   *
    * @return string
    */
-  protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId) {
+  protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor) {
 
     if ($field == 'id') {
       return $iterationDAO->contact_id;
@@ -2002,7 +1995,8 @@ WHERE  {$whereClause}";
         }
       }
     }
-    elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) {
+    elseif ($processor->isExportSpecifiedPaymentFields() && array_key_exists($field, self::componentPaymentFields())) {
+      $paymentTableId = $processor->getPaymentTableID();
       $paymentData = CRM_Utils_Array::value($iterationDAO->$paymentTableId, $paymentDetails);
       $payFieldMapper = array(
         'componentPaymentField_total_amount' => 'total_amount',
index 8efc7102551c7b3893d8c16b8ef9d7bb61103633..7f7a0569ca0a07016a437c2f4c90692a44151a1d 100644 (file)
@@ -88,6 +88,11 @@ class CRM_Export_BAO_ExportProcessor {
    */
   protected $relationshipReturnProperties = [];
 
+  /**
+   * @var array
+   */
+  protected $returnProperties = [];
+
   /**
    * CRM_Export_BAO_ExportProcessor constructor.
    *
@@ -117,6 +122,21 @@ class CRM_Export_BAO_ExportProcessor {
     $this->requestedFields = $requestedFields;
   }
 
+
+  /**
+   * @return array
+   */
+  public function getReturnProperties() {
+    return $this->returnProperties;
+  }
+
+  /**
+   * @param array $returnProperties
+   */
+  public function setReturnProperties($returnProperties) {
+    $this->returnProperties = $returnProperties;
+  }
+
   /**
    * @return array
    */
@@ -310,9 +330,25 @@ class CRM_Export_BAO_ExportProcessor {
       ])) {
       return TRUE;
     }
+    elseif ($this->isExportSpecifiedPaymentFields()) {
+      return TRUE;
+    }
     return FALSE;
   }
 
+  /**
+   * Has specific payment fields been requested (as opposed to via all fields).
+   *
+   * If specific fields have been requested then they get added at various points.
+   *
+   * @return bool
+   */
+  public function isExportSpecifiedPaymentFields() {
+    if ($this->getRequestedFields() !== NULL && $this->hasRequestedComponentPaymentFields()) {
+      return TRUE;
+    }
+  }
+
   /**
    * Get the name of the id field in the table that connects contributions to the export entity.
    */
@@ -325,9 +361,42 @@ class CRM_Export_BAO_ExportProcessor {
       ];
       return isset($mapping[$this->getQueryMode()]) ? $mapping[$this->getQueryMode()] : '';
     }
+    elseif ($this->hasRequestedComponentPaymentFields()) {
+      return 'participant_id';
+    }
     return FALSE;
   }
 
+  /**
+   * Have component payment fields been requested.
+   *
+   * @return bool
+   */
+  protected function hasRequestedComponentPaymentFields() {
+    if ($this->getQueryMode() === CRM_Contact_BAO_Query::MODE_EVENT) {
+      $participantPaymentFields = array_intersect_key($this->getComponentPaymentFields(), $this->getReturnProperties());
+      if (!empty($participantPaymentFields)) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Get fields that indicate payment fields have been requested for a component.
+   *
+   * @return array
+   */
+  protected function getComponentPaymentFields() {
+    return [
+      'componentPaymentField_total_amount' => ts('Total Amount'),
+      'componentPaymentField_contribution_status' => ts('Contribution Status'),
+      'componentPaymentField_received_date' => ts('Date Received'),
+      'componentPaymentField_payment_instrument' => ts('Payment Method'),
+      'componentPaymentField_transaction_id' => ts('Transaction ID'),
+    ];
+  }
+
   /**
    * Get the default properties when not specified.
    *
index 1140be9e5a8161ecb98cf39b685420b0d5d70d2a..5e375b6579402f6111c39f2a9cd06f35b7c266a3 100644 (file)
@@ -843,9 +843,11 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
    * @param $selectedFields
    * @param int $id
    *
+   * @param int $exportMode
+   *
    * @return array
    */
-  protected function doExport($selectedFields, $id) {
+  protected function doExport($selectedFields, $id, $exportMode = CRM_Export_Form_Select::CONTACT_EXPORT) {
     list($tableName, $sqlColumns) = CRM_Export_BAO_Export::exportComponents(
       TRUE,
       array($id),
@@ -853,7 +855,7 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
       NULL,
       $selectedFields,
       NULL,
-      CRM_Export_Form_Select::CONTACT_EXPORT,
+      $exportMode,
       "contact_a.id IN ({$id})",
       NULL,
       FALSE,
@@ -1370,10 +1372,31 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
   public function testExportSpecifyFields($exportMode, $selectedFields, $expected) {
     $this->ensureComponentIsEnabled($exportMode);
     $this->setUpContributionExportData();
-    list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1]);
+    list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], $exportMode);
     $this->assertEquals($expected, $sqlColumns);
   }
 
+  /**
+   * Test export fields when no payment fields to be exported.
+   */
+  public function textExportParticipantSpecifyFieldsNoPayment() {
+    $selectedFields = $this->getAllSpecifiableParticipantReturnFields();
+    foreach ($selectedFields as $index => $field) {
+      if (substr($field[1], 0, 22) === 'componentPaymentField_') {
+        unset ($selectedFields[$index]);
+      }
+    }
+
+    $expected = $this->getAllSpecifiableParticipantReturnFields();
+    foreach ($expected as $index => $field) {
+      if (substr($index, 0, 22) === 'componentPaymentField_') {
+        unset ($expected[$index]);
+      }
+    }
+
+    list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], CRM_Export_Form_Select::EVENT_EXPORT);
+    $this->assertEquals($expected, $sqlColumns);
+  }
   /**
    * Get all return fields (@todo - still being built up.
    *
@@ -1384,42 +1407,51 @@ class CRM_Export_BAO_ExportTest extends CiviUnitTestCase {
       [
         CRM_Export_Form_Select::EVENT_EXPORT,
         $this->getAllSpecifiableParticipantReturnFields(),
-        [
-          'participant_campaign_id' => 'participant_campaign_id varchar(128)',
-          'participant_contact_id' => 'participant_contact_id varchar(16)',
-          'componentpaymentfield_contribution_status' => 'componentpaymentfield_contribution_status text',
-          'currency' => 'currency varchar(3)',
-          'componentpaymentfield_received_date' => 'componentpaymentfield_received_date text',
-          'default_role_id' => 'default_role_id varchar(16)',
-          'participant_discount_name' => 'participant_discount_name varchar(16)',
-          'event_id' => 'event_id varchar(16)',
-          'event_end_date' => 'event_end_date varchar(32)',
-          'event_start_date' => 'event_start_date varchar(32)',
-          'template_title' => 'template_title varchar(255)',
-          'event_title' => 'event_title varchar(255)',
-          'participant_fee_amount' => 'participant_fee_amount varchar(32)',
-          'participant_fee_currency' => 'participant_fee_currency varchar(3)',
-          'fee_label' => 'fee_label varchar(255)',
-          'participant_fee_level' => 'participant_fee_level longtext',
-          'participant_is_pay_later' => 'participant_is_pay_later varchar(16)',
-          'participant_id' => 'participant_id varchar(16)',
-          'participant_note' => 'participant_note text',
-          'participant_role_id' => 'participant_role_id varchar(128)',
-          'participant_role' => 'participant_role varchar(255)',
-          'participant_source' => 'participant_source varchar(128)',
-          'participant_status_id' => 'participant_status_id varchar(16)',
-          'participant_status' => 'participant_status varchar(255)',
-          'participant_register_date' => 'participant_register_date varchar(32)',
-          'participant_registered_by_id' => 'participant_registered_by_id varchar(16)',
-          'participant_is_test' => 'participant_is_test varchar(16)',
-          'componentpaymentfield_total_amount' => 'componentpaymentfield_total_amount text',
-          'componentpaymentfield_transaction_id' => 'componentpaymentfield_transaction_id varchar(255)',
-          'transferred_to_contact_id' => 'transferred_to_contact_id varchar(16)',
-        ],
+        $this->getAllSpecifiableParticipantReturnColumns(),
       ],
     ];
   }
 
+  /**
+   * Get expected return column output for participant mode return all columns.
+   *
+   * @return array
+   */
+  public function getAllSpecifiableParticipantReturnColumns() {
+    return [
+      'participant_campaign_id' => 'participant_campaign_id varchar(128)',
+      'participant_contact_id' => 'participant_contact_id varchar(16)',
+      'componentpaymentfield_contribution_status' => 'componentpaymentfield_contribution_status text',
+      'currency' => 'currency varchar(3)',
+      'componentpaymentfield_received_date' => 'componentpaymentfield_received_date text',
+      'default_role_id' => 'default_role_id varchar(16)',
+      'participant_discount_name' => 'participant_discount_name varchar(16)',
+      'event_id' => 'event_id varchar(16)',
+      'event_end_date' => 'event_end_date varchar(32)',
+      'event_start_date' => 'event_start_date varchar(32)',
+      'template_title' => 'template_title varchar(255)',
+      'event_title' => 'event_title varchar(255)',
+      'participant_fee_amount' => 'participant_fee_amount varchar(32)',
+      'participant_fee_currency' => 'participant_fee_currency varchar(3)',
+      'fee_label' => 'fee_label varchar(255)',
+      'participant_fee_level' => 'participant_fee_level longtext',
+      'participant_is_pay_later' => 'participant_is_pay_later varchar(16)',
+      'participant_id' => 'participant_id varchar(16)',
+      'participant_note' => 'participant_note text',
+      'participant_role_id' => 'participant_role_id varchar(128)',
+      'participant_role' => 'participant_role varchar(255)',
+      'participant_source' => 'participant_source varchar(128)',
+      'participant_status_id' => 'participant_status_id varchar(16)',
+      'participant_status' => 'participant_status varchar(255)',
+      'participant_register_date' => 'participant_register_date varchar(32)',
+      'participant_registered_by_id' => 'participant_registered_by_id varchar(16)',
+      'participant_is_test' => 'participant_is_test varchar(16)',
+      'componentpaymentfield_total_amount' => 'componentpaymentfield_total_amount text',
+      'componentpaymentfield_transaction_id' => 'componentpaymentfield_transaction_id varchar(255)',
+      'transferred_to_contact_id' => 'transferred_to_contact_id varchar(16)',
+    ];
+  }
+
   /**
    * @return array
    */