From c41bd1e2580641f1652bdcc7d75455fab46a97f4 Mon Sep 17 00:00:00 2001 From: eileen Date: Mon, 23 Jul 2018 22:01:21 +1200 Subject: [PATCH] Rationalise selectedPaymentFields. 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 | 48 ++++----- CRM/Export/BAO/ExportProcessor.php | 69 +++++++++++++ tests/phpunit/CRM/Export/BAO/ExportTest.php | 103 +++++++++++++------- 3 files changed, 158 insertions(+), 62 deletions(-) diff --git a/CRM/Export/BAO/Export.php b/CRM/Export/BAO/Export.php index 478942d0b120..77be49e28376 100644 --- a/CRM/Export/BAO/Export.php +++ b/CRM/Export/BAO/Export.php @@ -308,9 +308,6 @@ public static function exportComponents( $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 @@ -372,14 +369,6 @@ public static function exportComponents( 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; } @@ -393,6 +382,9 @@ public static function exportComponents( 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 @@ -543,14 +535,14 @@ public static function exportComponents( $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; @@ -578,7 +570,7 @@ public static function exportComponents( // 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) { @@ -629,7 +621,7 @@ public static function exportComponents( 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); } } @@ -654,7 +646,7 @@ public static function exportComponents( // 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)) { @@ -1608,10 +1600,10 @@ public static function componentPaymentFields() { * @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 @@ -1690,7 +1682,7 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processo } 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 { @@ -1714,7 +1706,7 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processo * @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. @@ -1731,7 +1723,7 @@ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processo * - 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'); @@ -1740,7 +1732,7 @@ public static function getExportStructureArrays($returnProperties, $processor, $ 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) { @@ -1765,7 +1757,7 @@ public static function getExportStructureArrays($returnProperties, $processor, $ $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'); } @@ -2000,12 +1992,13 @@ protected static function buildRelatedContactArray($selectAll, $ids, $exportMode * @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; @@ -2082,7 +2075,8 @@ protected static function getTransformedFieldValue($field, $iterationDAO, $field } } } - 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', diff --git a/CRM/Export/BAO/ExportProcessor.php b/CRM/Export/BAO/ExportProcessor.php index cfdc0f5881d5..b925e656c72e 100644 --- a/CRM/Export/BAO/ExportProcessor.php +++ b/CRM/Export/BAO/ExportProcessor.php @@ -81,6 +81,11 @@ class CRM_Export_BAO_ExportProcessor { */ protected $relationshipTypes = []; + /** + * @var array + */ + protected $returnProperties = []; + /** * CRM_Export_BAO_ExportProcessor constructor. * @@ -110,6 +115,21 @@ public function setRequestedFields($requestedFields) { $this->requestedFields = $requestedFields; } + + /** + * @return array + */ + public function getReturnProperties() { + return $this->returnProperties; + } + + /** + * @param array $returnProperties + */ + public function setReturnProperties($returnProperties) { + $this->returnProperties = $returnProperties; + } + /** * @return array */ @@ -303,9 +323,25 @@ public function isExportPaymentFields() { ])) { 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. */ @@ -318,9 +354,42 @@ public function getPaymentTableID() { ]; 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. * diff --git a/tests/phpunit/CRM/Export/BAO/ExportTest.php b/tests/phpunit/CRM/Export/BAO/ExportTest.php index 0891e47c8425..da0d1f8bd792 100644 --- a/tests/phpunit/CRM/Export/BAO/ExportTest.php +++ b/tests/phpunit/CRM/Export/BAO/ExportTest.php @@ -842,9 +842,12 @@ protected function setUpHousehold() { /** * @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), @@ -852,7 +855,7 @@ protected function doExport($selectedFields, $id) { NULL, $selectedFields, NULL, - CRM_Export_Form_Select::CONTACT_EXPORT, + $exportMode, "contact_a.id IN ({$id})", NULL, FALSE, @@ -1369,10 +1372,31 @@ public function testGetSQLColumns($exportMode, $expected) { 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. * @@ -1383,42 +1407,51 @@ public function getAllSpecifiableReturnFields() { [ 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 */