From c1413e289bae26c91c605f3367a9df808ed0cc79 Mon Sep 17 00:00:00 2001 From: Dave Greenberg Date: Fri, 14 Nov 2014 11:14:38 -0800 Subject: [PATCH] CRM-15453 - New Recur contribution report class, template and report instance. ---------------------------------------- * CRM-15453: https://issues.civicrm.org/jira/browse/CRM-15453 --- CRM/Report/Form/Contribute/Recur.php | 327 ++++++++++++++++++ .../Incremental/sql/4.6.alpha1.mysql.tpl | 14 +- xml/templates/civicrm_data.tpl | 1 + xml/templates/civicrm_navigation.tpl | 5 + 4 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 CRM/Report/Form/Contribute/Recur.php diff --git a/CRM/Report/Form/Contribute/Recur.php b/CRM/Report/Form/Contribute/Recur.php new file mode 100644 index 0000000000..d09e0f9681 --- /dev/null +++ b/CRM/Report/Form/Contribute/Recur.php @@ -0,0 +1,327 @@ +_columns = array( + 'civicrm_contact' => array( + 'dao' => 'CRM_Contact_DAO_Contact', + 'order_bys' => array( + 'sort_name' => array( + 'title' => ts("Last name, First name"), + ), + ), + 'fields' => array( + 'sort_name' => array( + 'title' => ts('Contact Name'), + 'no_repeat' => TRUE, + 'default' => TRUE, + ), + 'id' => array( + 'no_display' => TRUE, + 'required' => TRUE, + ), + ), + ), + 'civicrm_email' => array( + 'dao' => 'CRM_Core_DAO_Email', + 'fields' => array( + 'email' => array( + 'title' => ts('Email'), + 'no_repeat' => TRUE, + ), + ), + 'grouping' => 'contact-fields', + ), + 'civicrm_phone' => array( + 'dao' => 'CRM_Core_DAO_Phone', + 'fields' => array( + 'phone' => array( + 'title' => ts('Phone'), + 'no_repeat' => TRUE, + ), + ), + 'grouping' => 'contact-fields', + ), + 'civicrm_contribution' => array( + 'dao' => 'CRM_Contribute_DAO_Contribution', + 'fields' => array( + 'id' => array( + 'no_display' => TRUE, + 'required' => TRUE, + ), + 'total_amount' => array( + 'title' => ts('Amount Contributed to Date'), + 'statistics' => array( + 'sum' => ts("Total Amount Contributed") + ), + ), + ), + ), + 'civicrm_contribution_recur' => array( + 'dao' => 'CRM_Contribute_DAO_ContributionRecur', + 'fields' => array( + 'id' => array( + 'no_display' => TRUE, + 'required' => TRUE, + ), + 'currency' => array( + 'title' => ts("Currency"), + 'required' => TRUE, + 'no_display' => TRUE, + ), + 'amount' => array( + 'title' => ts('Amount'), + 'default' => TRUE, + ), + 'contribution_status_id' => array( + 'title' => ts('Donation Status'), + ), + 'frequency_interval' => array( + 'title' => ts('Frequency interval'), + 'default' => TRUE, + ), + 'frequency_unit' => array( + 'title' => ts('Frequency unit'), + 'default' => TRUE, + ), + 'installments' => array( + 'title' => ts('Installments'), + 'default' => TRUE, + ), + 'start_date' => array( + 'title' => ts('Start Date'), + ), + 'create_date' => array( + 'title' => ts('Create Date'), + ), + 'modified_date' => array( + 'title' => ts('Modified Date'), + ), + 'cancel_date' => array( + 'title' => ts('Cancel Date'), + ), + 'end_date' => array( + 'title' => ts('End Date'), + ), + 'next_sched_contribution_date' => array( + 'title' => ts('Next Scheduled Contribution Date'), + ), + 'failure_count' => array( + 'title' => ts('Failure Count'), + ), + 'failure_retry_date' => array( + 'title' => ts('Failure Retry Date'), + ), + ), + 'filters' => array( + 'contribution_status_id' => array( + 'title' => ts('Donation Status'), + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Contribute_PseudoConstant::contributionStatus(), + 'default' => array(5), + 'type' => CRM_Utils_Type::T_INT, + ), + 'currency' => array( + 'title' => 'Currency', + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Core_OptionGroup::values('currencies_enabled'), + 'default' => NULL, + 'type' => CRM_Utils_Type::T_STRING, + ), + 'financial_type_id' => array( + 'title' => ts('Financial Type'), + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Contribute_PseudoConstant::financialType(), + 'type' => CRM_Utils_Type::T_INT, + ), + 'frequency_unit' => array( + 'title' => ts('Frequency Unit'), + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Core_OptionGroup::values('recur_frequency_units'), + 'type' => CRM_Utils_Type::T_INT, + ), + 'frequency_interval' => array( + 'title' => ts('Frequency Interval'), + 'type' => CRM_Utils_Type::T_INT, + ), + 'installments' => array( + 'title' => ts('Installments'), + 'type' => CRM_Utils_Type::T_INT, + ), + 'start_date' => array( + 'title' => ts('Start Date'), + 'operatorType' => CRM_Report_Form::OP_DATE, + 'type' => CRM_Utils_Type::T_TIME, + ), + 'next_sched_contribution_date' => array( + 'title' => ts('Next Scheduled Contribution Date'), + 'operatorType' => CRM_Report_Form::OP_DATE, + 'type' => CRM_Utils_Type::T_TIME, + ), + 'end_date' => array( + 'title' => ts('End Date'), + 'operatorType' => CRM_Report_Form::OP_DATE, + 'type' => CRM_Utils_Type::T_TIME, + ), + 'calculated_end_date' => array( + 'title' => ts('Calculated end date (either end date or date all installments will be made)'), + 'description' => "does this work?", + 'operatorType' => CRM_Report_Form::OP_DATE, + 'pseudofield' => TRUE + ), + ), + ) + ); + $this->_currencyColumn = 'civicrm_contribution_recur_currency'; + parent::__construct(); + } + function getTemplateName() { + return 'CRM/Report/Form.tpl' ; + } + + function from() { + $this->_from = " + FROM civicrm_contact {$this->_aliases['civicrm_contact']} + INNER JOIN civicrm_contribution_recur {$this->_aliases['civicrm_contribution_recur']} + ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_contribution_recur']}.contact_id"; + $this->_from .= " + LEFT JOIN civicrm_contribution {$this->_aliases['civicrm_contribution']} + ON {$this->_aliases['civicrm_contribution_recur']}.id = {$this->_aliases['civicrm_contribution']}.contribution_recur_id"; + $this->_from .= " + LEFT JOIN civicrm_email {$this->_aliases['civicrm_email']} + ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_email']}.contact_id"; + $this->_from .= " + LEFT JOIN civicrm_phone {$this->_aliases['civicrm_phone']} + ON ({$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_phone']}.contact_id AND + {$this->_aliases['civicrm_phone']}.is_primary = 1)"; + } + + function groupBy() { + $this->_groupBy = "GROUP BY " . $this->_aliases['civicrm_contribution_recur'] . ".id"; + } + + function where() { + parent::where(); + // Handle calculated end date. This can come from one of two sources: + // Either there is a specified end date for the end_date field + // Or, we calculate the end date based on the start date + + // installments * intervals using the mysql date_add function, along + // with the interval unit (e.g. DATE_ADD(start_date, INTERVAL 12 * 1 MONTH) + $date_suffixes = array('relative', 'from', 'to'); + while(list(,$suffix) = each($date_suffixes)) { + // Check to see if the user wants to search by calculated date. + if(!empty($this->_params['calculated_end_date_' . $suffix])) { + // The calculated date field is in use - spring into action + // Gather values + $relative = CRM_Utils_Array::value("calculated_end_date_relative", $this->_params); + $from = CRM_Utils_Array::value("calculated_end_date_from", $this->_params); + $to = CRM_Utils_Array::value("calculated_end_date_to", $this->_params); + $end_date_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['end_date']['dbAlias']; + $end_date_type = $this->_columns['civicrm_contribution_recur']['filters']['end_date']['type']; + $start_date_type = $this->_columns['civicrm_contribution_recur']['filters']['start_date']['type']; + $frequency_unit_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['frequency_unit']['dbAlias']; + $frequency_interval_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['frequency_interval']['dbAlias']; + $installments_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['installments']['dbAlias']; + $start_date_db_alias = $this->_columns['civicrm_contribution_recur']['filters']['start_date']['dbAlias']; + + // The end date clause is simple to construct + $end_date_clause = $this->dateClause($end_date_db_alias, $relative, $from, $to, $end_date_type, NULL, NULL); + + // NOTE: For the calculation based on installment, there doesn't + // seem to be a way to include the interval unit (e.g. month, + // date, etc) as a field name - so we have to build a complex + // OR statement instead. + + $installment_clause = '(' . + $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias,1) month)", + $relative, $from, $to, $start_date_type, NULL, NULL); + $installment_clause .= " AND $frequency_unit_db_alias = 'month' ) OR \n"; + + $installment_clause .= '(' . + $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias,1) day)", + $relative, $from, $to, $start_date_type, NULL, NULL); + $installment_clause .= " AND $frequency_unit_db_alias = 'day' ) OR \n"; + + $installment_clause .= '(' . + $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias, 1) week)", + $relative, $from, $to, $start_date_type, NULL, NULL); + $installment_clause .= " AND $frequency_unit_db_alias = 'week' ) OR \n"; + + $installment_clause .= '(' . + $this->dateClause("DATE_ADD($start_date_db_alias, INTERVAL $installments_db_alias * COALESCE($frequency_interval_db_alias, 1) year)", + $relative, $from, $to, $start_date_type, NULL, NULL); + $installment_clause .= " AND $frequency_unit_db_alias = 'year' )\n"; + + $this->_where .= " AND "; + $this->_where .= "("; + $this->_where .= "($end_date_db_alias IS NOT NULL AND $end_date_clause)\n"; + $this->_where .= " OR \n"; + $this->_where .= "($installments_db_alias IS NOT NULL AND ($installment_clause))\n"; + $this->_where .= ')'; + break; + } + } + } + + + function alterDisplay(&$rows) { + $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(); + foreach ($rows as $rowNum => $row) { + // convert display name to links + if (array_key_exists('civicrm_contact_sort_name', $row) && + CRM_Utils_Array::value('civicrm_contact_sort_name', $rows[$rowNum]) && + array_key_exists('civicrm_contact_id', $row) + ) { + $url = CRM_Utils_System::url('civicrm/contact/view', + 'reset=1&cid=' . $row['civicrm_contact_id'], + $this->_absoluteUrl + ); + $rows[$rowNum]['civicrm_contact_sort_name_link'] = $url; + $rows[$rowNum]['civicrm_contact_sort_name_hover'] = ts('View Contact Summary for this Contact.'); + } + + // handle contribution status id + if ($value = CRM_Utils_Array::value('civicrm_contribution_recur_contribution_status_id', $row)) { + $rows[$rowNum]['civicrm_contribution_recur_contribution_status_id'] = $contributionStatus[$value]; + } + + if ($value = CRM_Utils_Array::value('civicrm_contribution_recur_amount', $row)) { + $rows[$rowNum]['civicrm_contribution_recur_amount'] = CRM_Utils_Money::format($rows[$rowNum]['civicrm_contribution_recur_amount'],$rows[$rowNum]['civicrm_contribution_recur_currency']); + } + + } + } +} \ No newline at end of file diff --git a/CRM/Upgrade/Incremental/sql/4.6.alpha1.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.6.alpha1.mysql.tpl index 9fd13b68a1..0fef707193 100644 --- a/CRM/Upgrade/Incremental/sql/4.6.alpha1.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/4.6.alpha1.mysql.tpl @@ -80,4 +80,16 @@ ALTER TABLE civicrm_mailing ADD COLUMN location_type_id INT(10) unsigned DEFAULT ALTER TABLE civicrm_mailing ADD COLUMN email_selection_method varchar(20) DEFAULT 'automatic' COMMENT 'With location_type_id, determine how to choose the email address to use.'; -- CRM-15500 fix -ALTER TABLE `civicrm_action_schedule` CHANGE `limit_to` `limit_to` TINYINT( 4 ) NULL DEFAULT NULL; \ No newline at end of file +ALTER TABLE `civicrm_action_schedule` CHANGE `limit_to` `limit_to` TINYINT( 4 ) NULL DEFAULT NULL; + +-- CRM-15453 Recurring Contributions report template AND instance +SELECT @option_group_id_report := MAX(id) FROM civicrm_option_group WHERE name = 'report_template'; +SELECT @weight := MAX(weight) FROM civicrm_option_value WHERE option_group_id = @option_group_id_report; +SELECT @contribCompId := MAX(id) FROM civicrm_component where name = 'CiviContribute'; +INSERT INTO civicrm_option_value +(option_group_id, {localize field='label'}label{/localize}, value, name, weight, {localize field='description'}description{/localize}, is_active, component_id) VALUES +(@option_group_id_report, {localize}'Recurring Contributions Report'{/localize}, 'contribute/recur', 'CRM_Report_Form_Contribute_Recur', @weight := @weight + 1, {localize}'Shows information about the status of recurring contributions'{/localize}, 1, @contribCompId); +INSERT INTO `civicrm_report_instance` +( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) +VALUES +( {$domainID}, 'Pending Recurring Contributions', 'contribute/recur', 'Shows all pending recurring contributions', 'access CiviContribute', '{literal}a:39:{s:6:"fields";a:7:{s:9:"sort_name";s:1:"1";s:6:"amount";s:1:"1";s:22:"contribution_status_id";s:1:"1";s:18:"frequency_interval";s:1:"1";s:14:"frequency_unit";s:1:"1";s:12:"installments";s:1:"1";s:8:"end_date";s:1:"1";}s:25:"contribution_status_id_op";s:2:"in";s:28:"contribution_status_id_value";a:1:{i:0;s:1:"5";}s:11:"currency_op";s:2:"in";s:14:"currency_value";a:0:{}s:20:"financial_type_id_op";s:2:"in";s:23:"financial_type_id_value";a:0:{}s:17:"frequency_unit_op";s:2:"in";s:20:"frequency_unit_value";a:0:{}s:22:"frequency_interval_min";s:0:"";s:22:"frequency_interval_max";s:0:"";s:21:"frequency_interval_op";s:3:"lte";s:24:"frequency_interval_value";s:0:"";s:16:"installments_min";s:0:"";s:16:"installments_max";s:0:"";s:15:"installments_op";s:3:"lte";s:18:"installments_value";s:0:"";s:19:"start_date_relative";s:0:"";s:15:"start_date_from";s:0:"";s:13:"start_date_to";s:0:"";s:37:"next_sched_contribution_date_relative";s:0:"";s:33:"next_sched_contribution_date_from";s:0:"";s:31:"next_sched_contribution_date_to";s:0:"";s:17:"end_date_relative";s:0:"";s:13:"end_date_from";s:0:"";s:11:"end_date_to";s:0:"";s:28:"calculated_end_date_relative";s:0:"";s:24:"calculated_end_date_from";s:0:"";s:22:"calculated_end_date_to";s:0:"";s:9:"order_bys";a:1:{i:1;a:1:{s:6:"column";s:1:"-";}}s:11:"description";s:41:"Shows all pending recurring contributions";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:9:"row_count";s:0:"";s:14:"addToDashboard";s:1:"1";s:10:"permission";s:21:"access CiviContribute";s:9:"parent_id";s:0:"";s:11:"instance_id";N;}{/literal}'); \ No newline at end of file diff --git a/xml/templates/civicrm_data.tpl b/xml/templates/civicrm_data.tpl index 4072cfb850..7b7a16013d 100644 --- a/xml/templates/civicrm_data.tpl +++ b/xml/templates/civicrm_data.tpl @@ -620,6 +620,7 @@ VALUES (@option_group_id_report , '{ts escape="sql"}Contribution Aggregate by Relationship{/ts}', 'contribute/history', 'CRM_Report_Form_Contribute_History', NULL, 0, NULL, 46, '{ts escape="sql"}List contact's donation history, grouped by year, along with contributions attributed to any of the contact's related contacts.{/ts}', 0, 0, 1, @contributeCompId, NULL), (@option_group_id_report, {localize}'{ts escape="sql"}Mail Detail Report{/ts}'{/localize}, 'mailing/detail', 'CRM_Report_Form_Mailing_Detail', NULL, 0, NULL, 47, {localize}'{ts escape="sql"}Provides reporting on Intended and Successful Deliveries, Unsubscribes and Opt-outs, Replies and Forwards.{/ts}'{/localize}, 0, 0, 1, @mailCompId, NULL), (@option_group_id_report, {localize}'{ts escape="sql"}Contribution and Membership Details{/ts}'{/localize}, 'member/contributionDetail', 'CRM_Report_Form_Member_ContributionDetail', NULL, 0, NULL, 48, {localize}'{ts escape="sql"}Contribution details for any type of contribution, plus associated membership information for contributions which are in payment for memberships.{/ts}'{/localize}, 0, 0, 1, @memberCompId, NULL), + (@option_group_id_report, {localize}'{ts escape="sql"}Recurring Contributions Report{/ts}'{/localize}, 'contribute/recur', 'CRM_Report_Form_Contribute_Recur', NULL, 0, NULL, 49, {localize}'{ts escape="sql"}Provides information about the status of recurring contributions{/ts}'{/localize}, 0, 0, 1, @contributeCompId, NULL), (@option_group_id_acs, '{ts escape="sql"}Scheduled{/ts}', 1, 'Scheduled', NULL, 0, 1, 1, NULL, 0, 1, 1, NULL, NULL), (@option_group_id_acs, '{ts escape="sql"}Completed{/ts}', 2, 'Completed', NULL, 0, NULL, 2, NULL, 0, 1, 1, NULL, NULL), diff --git a/xml/templates/civicrm_navigation.tpl b/xml/templates/civicrm_navigation.tpl index e48bd4c05a..e43c9078d3 100644 --- a/xml/templates/civicrm_navigation.tpl +++ b/xml/templates/civicrm_navigation.tpl @@ -770,6 +770,11 @@ INSERT INTO `civicrm_report_instance` VALUES ( @domainID, '{ts escape="sql" skip="true"}Bookkeeping Transactions{/ts}', 'contribute/bookkeeping', '{ts escape="sql" skip="true"}Provides transaction details for all contributions and payments, including Transaction #, Invoice ID, Payment Instrument and Check #.{/ts}', 'access CiviContribute', '{literal}a:40:{s:6:"fields";a:12:{s:9:"sort_name";s:1:"1";s:21:"debit_accounting_code";s:1:"1";s:22:"credit_accounting_code";s:1:"1";s:17:"financial_type_id";s:1:"1";s:12:"receive_date";s:1:"1";s:22:"contribution_status_id";s:1:"1";s:2:"id";s:1:"1";s:12:"check_number";s:1:"1";s:21:"payment_instrument_id";s:1:"1";s:9:"trxn_date";s:1:"1";s:7:"trxn_id";s:1:"1";s:6:"amount";s:1:"1";}s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:6:"id_min";s:0:"";s:6:"id_max";s:0:"";s:5:"id_op";s:3:"lte";s:8:"id_value";s:0:"";s:24:"debit_accounting_code_op";s:2:"in";s:27:"debit_accounting_code_value";a:0:{}s:25:"credit_accounting_code_op";s:2:"in";s:28:"credit_accounting_code_value";a:0:{}s:13:"debit_name_op";s:2:"in";s:16:"debit_name_value";a:0:{}s:14:"credit_name_op";s:2:"in";s:17:"credit_name_value";a:0:{}s:20:"financial_type_id_op";s:2:"in";s:23:"financial_type_id_value";a:0:{}s:21:"receive_date_relative";s:1:"0";s:17:"receive_date_from";s:0:"";s:15:"receive_date_to";s:0:"";s:25:"contribution_status_id_op";s:2:"in";s:28:"contribution_status_id_value";a:1:{i:0;s:1:"1";}s:24:"payment_instrument_id_op";s:2:"in";s:27:"payment_instrument_id_value";a:0:{}s:18:"trxn_date_relative";s:1:"0";s:14:"trxn_date_from";s:0:"";s:12:"trxn_date_to";s:0:"";s:10:"amount_min";s:0:"";s:10:"amount_max";s:0:"";s:9:"amount_op";s:3:"lte";s:12:"amount_value";s:0:"";s:11:"description";s:133:"Provides transaction details for all contributions and payments, including Transaction #, Invoice ID, Payment Instrument and Check #.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:21:"access CiviContribute";s:9:"parent_id";s:0:"";s:6:"groups";s:0:"";s:9:"domain_id";i:1;s:11:"is_reserved";b:0;}{/literal}'); +INSERT INTO `civicrm_report_instance` + ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) +VALUES + ( @domainID, '{ts escape="sql" skip="true"}Recurring Contributions{/ts}', 'contribute/recur', '{ts escape="sql" skip="true"}Provides information about the status of recurring contributions{/ts}', 'access CiviContribute', '{literal}a:39:{s:6:"fields";a:7:{s:9:"sort_name";s:1:"1";s:6:"amount";s:1:"1";s:22:"contribution_status_id";s:1:"1";s:18:"frequency_interval";s:1:"1";s:14:"frequency_unit";s:1:"1";s:12:"installments";s:1:"1";s:8:"end_date";s:1:"1";}s:25:"contribution_status_id_op";s:2:"in";s:28:"contribution_status_id_value";a:1:{i:0;s:1:"5";}s:11:"currency_op";s:2:"in";s:14:"currency_value";a:0:{}s:20:"financial_type_id_op";s:2:"in";s:23:"financial_type_id_value";a:0:{}s:17:"frequency_unit_op";s:2:"in";s:20:"frequency_unit_value";a:0:{}s:22:"frequency_interval_min";s:0:"";s:22:"frequency_interval_max";s:0:"";s:21:"frequency_interval_op";s:3:"lte";s:24:"frequency_interval_value";s:0:"";s:16:"installments_min";s:0:"";s:16:"installments_max";s:0:"";s:15:"installments_op";s:3:"lte";s:18:"installments_value";s:0:"";s:19:"start_date_relative";s:0:"";s:15:"start_date_from";s:0:"";s:13:"start_date_to";s:0:"";s:37:"next_sched_contribution_date_relative";s:0:"";s:33:"next_sched_contribution_date_from";s:0:"";s:31:"next_sched_contribution_date_to";s:0:"";s:17:"end_date_relative";s:0:"";s:13:"end_date_from";s:0:"";s:11:"end_date_to";s:0:"";s:28:"calculated_end_date_relative";s:0:"";s:24:"calculated_end_date_from";s:0:"";s:22:"calculated_end_date_to";s:0:"";s:9:"order_bys";a:1:{i:1;a:1:{s:6:"column";s:1:"-";}}s:11:"description";s:41:"Shows all pending recurring contributions";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:9:"row_count";s:0:"";s:14:"addToDashboard";s:1:"1";s:10:"permission";s:21:"access CiviContribute";s:9:"parent_id";s:0:"";s:11:"instance_id";N;}{/literal}'); + -- Membership reports INSERT INTO `civicrm_report_instance` ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) -- 2.25.1