Skip to content

Commit

Permalink
Merge pull request #3258 from dparker1005/sales-report-multiple-level…
Browse files Browse the repository at this point in the history
…s-codes

Allow filtering the sales/revenue report by multiple levels/discount codes
  • Loading branch information
kimcoleman authored Jan 21, 2025
2 parents 4fb4108 + 92ddda1 commit 2a0b9f0
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 45 deletions.
3 changes: 1 addition & 2 deletions adminpages/reports/logins.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ function pmpro_report_login_page()
<div class="pmpro_report-filters">
<h3><?php esc_html_e( 'Customize Report', 'paid-memberships-pro'); ?></h3>
<div class="tablenav top">
<label for="l"><?php echo esc_html_x( 'Show', 'Dropdown label, e.g. Show All Users', 'paid-memberships-pro' ); ?></label>
<label for="l" class="pmpro_report-filter-text"><?php echo esc_html_x( 'Show', 'Dropdown label, e.g. Show All Users', 'paid-memberships-pro' ); ?></label>
<select id="l" name="l" onchange="jQuery('#visits-views-logins-form').trigger('submit');" aria-label="<?php esc_attr_e( 'Select a membership level to customize this report', 'paid-memberships-pro' ); ?>">
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php esc_html_e('All Users', 'paid-memberships-pro')?></option>
<option value="all" <?php if($l == "all") { ?>selected="selected"<?php } ?>><?php esc_html_e('All Levels', 'paid-memberships-pro')?></option>
Expand All @@ -185,7 +185,6 @@ function pmpro_report_login_page()
}
?>
</select>
<br class="clear" />
</div> <!-- end tablenav -->
</div> <!-- end pmpro_report-filters -->
<?php if ( $theusers ) { ?>
Expand Down
13 changes: 6 additions & 7 deletions adminpages/reports/memberships.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ function pmpro_report_memberships_page() {
<div class="pmpro_report-filters">
<h3><?php esc_html_e( 'Customize Report', 'paid-memberships-pro' ); ?></h3>
<div class="tablenav top">
<span><?php echo esc_html_x( 'Show', 'Dropdown label, e.g. Show Period', 'paid-memberships-pro' ); ?></span>
<span class="pmpro_report-filter-text"><?php echo esc_html_x( 'Show', 'Dropdown label, e.g. Show Period', 'paid-memberships-pro' ); ?></span>
<label for="period" class="screen-reader-text"><?php esc_html_e( 'Select report time period', 'paid-memberships-pro' ); ?></label>
<select id="period" name="period">
<option value="daily" <?php selected( $period, 'daily' ); ?>><?php esc_html_e( 'Daily', 'paid-memberships-pro' ); ?></option>
Expand All @@ -357,7 +357,7 @@ function pmpro_report_memberships_page() {
<option value="signup_v_cancel" <?php selected( $type, 'signup_v_cancel' ); ?>><?php esc_html_e( 'Signups vs. Cancellations', 'paid-memberships-pro' ); ?></option>
<option value="signup_v_expiration" <?php selected( $type, 'signup_v_expiration' ); ?>><?php esc_html_e( 'Signups vs. Expirations', 'paid-memberships-pro' ); ?></option>
</select>
<span id="for"><?php esc_html_e( 'for', 'paid-memberships-pro' ); ?></span>
<span id="for" class="pmpro_report-filter-text"><?php esc_html_e( 'for', 'paid-memberships-pro' ); ?></span>
<label for="month" class="screen-reader-text"><?php esc_html_e( 'Select report month', 'paid-memberships-pro' ); ?></label>
<select id="month" name="month">
<?php for ( $i = 1; $i < 13; $i++ ) { ?>
Expand All @@ -370,7 +370,7 @@ function pmpro_report_memberships_page() {
<option value="<?php echo esc_attr( $i ); ?>" <?php selected( $year, $i ); ?>><?php echo esc_html( $i ); ?></option>
<?php } ?>
</select>
<span id="for"><?php esc_html_e( 'for', 'paid-memberships-pro' ); ?></span>
<span id="for" class="pmpro_report-filter-text"><?php esc_html_e( 'for', 'paid-memberships-pro' ); ?></span>
<label for="level" class="screen-reader-text"><?php esc_html_e( 'Filter report by membership level', 'paid-memberships-pro' ); ?></label>
<select id="level" name="level">
<option value=""
Expand Down Expand Up @@ -422,11 +422,10 @@ function pmpro_report_memberships_page() {
<?php } ?>
</select>
<?php } ?>
<input type="hidden" name="page" value="pmpro-reports" />
<input type="hidden" name="report" value="memberships" />
<input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Generate Report', 'paid-memberships-pro' ); ?>" />
<br class="clear" />
</div> <!-- end tablenav -->
<input type="hidden" name="page" value="pmpro-reports" />
<input type="hidden" name="report" value="memberships" />
<input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Generate Report', 'paid-memberships-pro' ); ?>" />
</div> <!-- end pmpro_report-filters -->
<div class="pmpro_chart_area">
<div id="chart_div" style="clear: both; width: 100%; height: 500px;"></div>
Expand Down
81 changes: 56 additions & 25 deletions adminpages/reports/sales.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ function pmpro_report_sales_data( $args ){

$type_function = ! empty( $args['type_function'] ) ? $args['type_function'] : '';
$report_unit = ! empty( $args['report_unit'] ) ? $args['report_unit'] : '';
$discount_code = ! empty( $args['discount_code'] ) ? $args['discount_code'] : '';
$discount_code = ! empty( $args['discount_code'] ) ? $args['discount_code'] : array();
$startdate = ! empty( $args['startdate'] ) ? $args['startdate'] : '';
$enddate = ! empty( $args['enddate'] ) ? $args['enddate'] : '';
$l = ! empty( $args['l'] ) ? (int) $args['l'] : '';
$l = ! empty( $args['l'] ) ? $args['l'] : array();

//testing or live data
$gateway_environment = get_option( "pmpro_gateway_environment");
Expand Down Expand Up @@ -168,11 +168,22 @@ function pmpro_report_sales_data( $args ){
if(!empty($enddate))
$sqlQuery .= "AND mo1.timestamp <= DATE_ADD( '" . esc_sql( $enddate ) . " 23:59:59' , INTERVAL - " . esc_sql( $tz_offset ) . " SECOND )";

if(!empty($l))
$sqlQuery .= "AND mo1.membership_id IN(" . $l . ") "; // $l is already escaped. See declaration.
if ( ! empty( $l ) ) {
if ( is_array( $l ) ) {
$l_escaped = implode( ',', array_map( 'intval', $l ) );
} else {
$l_escaped = (int) $l;
}
$sqlQuery .= "AND mo1.membership_id IN(" . $l_escaped . ") "; // $l_escaped is already escaped. See above.
}

if ( ! empty( $discount_code ) ) {
$sqlQuery .= "AND dc.code_id = '" . esc_sql( $discount_code ) . "' ";
if ( is_array( $discount_code ) ) {
$discount_code_escaped = implode( ',', array_map( 'intval', $discount_code ) );
} else {
$discount_code_escaped = (int) $discount_code;
}
$sqlQuery .= "AND dc.code_id IN(" . $discount_code_escaped . ") "; // $discount_code_escaped is already escaped. See above.
}

$sqlQuery .= " GROUP BY mo1.id ";
Expand Down Expand Up @@ -217,15 +228,23 @@ function pmpro_report_sales_page()
}

if( ! empty( $_REQUEST['level'] ) ) {
$l = intval($_REQUEST['level']);
if ( is_array( $_REQUEST['level'] ) ) {
$l = array_map( 'intval', $_REQUEST['level'] );
} else {
$l = array( intval( $_REQUEST['level'] ) );
}
} else {
$l = "";
$l = array();
}

if ( ! empty( $_REQUEST[ 'discount_code' ] ) ) {
$discount_code = intval( $_REQUEST[ 'discount_code' ] );
if ( isset( $_REQUEST[ 'discount_code' ] ) ) {
if ( is_array( $_REQUEST[ 'discount_code' ] ) ) {
$discount_code = array_map( 'intval', $_REQUEST[ 'discount_code' ] );
} else {
$discount_code = array( intval( $_REQUEST[ 'discount_code' ] ) );
}
} else {
$discount_code = '';
$discount_code = array();
}

if ( isset( $_REQUEST[ 'show_parts' ] ) ) {
Expand Down Expand Up @@ -459,7 +478,7 @@ function pmpro_report_sales_page()
ksort( $dates );

// Save a transient for each combo of params. Expires in 1 hour.
$param_array = array( $period, $type, $month, $year, $l, $discount_code );
$param_array = array( $period, $type, $month, $year, implode( ',', $l ), implode( ',', $discount_code ) );
$param_hash = md5( implode( ' ', $param_array ) . PMPRO_VERSION );
set_transient( 'pmpro_sales_data_' . $param_hash, $csvdata, HOUR_IN_SECONDS );

Expand Down Expand Up @@ -598,7 +617,7 @@ function pmpro_report_sales_page()
<div class="pmpro_report-filters">
<h3><?php esc_html_e( 'Customize Report', 'paid-memberships-pro'); ?></h3>
<div class="tablenav top">
<span><?php echo esc_html_x( 'Show', 'Dropdown label, e.g. Show Period', 'paid-memberships-pro' ); ?></span>
<span class="pmpro_report-filter-text"><?php echo esc_html_x( 'Show', 'Dropdown label, e.g. Show Period', 'paid-memberships-pro' ); ?></span>
<label for="period" class="screen-reader-text"><?php esc_html_e( 'Select report time period', 'paid-memberships-pro' ); ?></label>
<select id="period" name="period">
<option value="daily" <?php selected($period, "daily");?>><?php esc_html_e('Daily', 'paid-memberships-pro' );?></option>
Expand All @@ -613,7 +632,7 @@ function pmpro_report_sales_page()
<option value="revenue" <?php selected($type, "revenue");?>><?php esc_html_e('Revenue', 'paid-memberships-pro' );?></option>
<option value="sales" <?php selected($type, "sales");?>><?php esc_html_e('Sales', 'paid-memberships-pro' );?></option>
</select>
<span id="for"><?php esc_html_e('for', 'paid-memberships-pro' )?></span>
<span id="for" class="pmpro_report-filter-text"><?php esc_html_e('for', 'paid-memberships-pro' )?></span>
<label for="month" class="screen-reader-text"><?php esc_html_e( 'Select report month', 'paid-memberships-pro' ); ?></label>
<select id="month" name="month">
<?php for($i = 1; $i < 13; $i++) { ?>
Expand All @@ -626,45 +645,57 @@ function pmpro_report_sales_page()
<option value="<?php echo esc_attr( $i );?>" <?php selected($year, $i);?>><?php echo esc_html( $i );?></option>
<?php } ?>
</select>
<span id="for"><?php esc_html_e('for', 'paid-memberships-pro' )?></span>
<span id="for" class="pmpro_report-filter-text"><?php esc_html_e('for', 'paid-memberships-pro' )?></span>
<label for="level" class="screen-reader-text"><?php esc_html_e( 'Filter report by membership level', 'paid-memberships-pro' ); ?></label>
<select id="level" name="level">
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php esc_html_e('All Levels', 'paid-memberships-pro' );?></option>
<select id="level" name="level[]" multiple>
<?php
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
$levels = pmpro_sort_levels_by_order( $levels );
foreach($levels as $level)
{
?>
<option value="<?php echo esc_attr( $level->id ); ?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo esc_html( $level->name); ?></option>
<option value="<?php echo esc_attr( $level->id ); ?>" <?php if ( in_array( $level->id, $l ) ) { ?>selected="selected"<?php } ?>><?php echo esc_html( $level->name); ?></option>
<?php
}
?>
</select>
</select>
<?php
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->pmpro_discount_codes ";
$sqlQuery .= "ORDER BY id DESC ";
$codes = $wpdb->get_results($sqlQuery, OBJECT);
if ( ! empty( $codes ) ) { ?>
<label for="discount_code" class="screen-reader-text"><?php esc_html_e( 'Filter report by discount code', 'paid-memberships-pro' ); ?></label>
<select id="discount_code" name="discount_code">
<option value="" <?php if ( empty( $discount_code ) ) { ?>selected="selected"<?php } ?>><?php esc_html_e('All Codes', 'paid-memberships-pro' );?></option>
<select id="discount_code" name="discount_code[]" multiple>
<?php foreach ( $codes as $code ) { ?>
<option value="<?php echo esc_attr( $code->id ); ?>" <?php selected( $discount_code, $code->id ); ?>><?php echo esc_html( $code->code ); ?></option>
<option value="<?php echo esc_attr( $code->id ); ?>" <?php if ( in_array( $code->id, $discount_code ) ) { ?>selected="selected"<?php } ?>><?php echo esc_html( $code->code ); ?></option>
<?php } ?>
</select>
<?php } ?>
<script>
// Make the level and discount code fields select2.
jQuery(document).ready(function() {
jQuery('#level').select2({
placeholder: '<?php esc_html_e( 'All Levels', 'paid-memberships-pro' ); ?>',
allowClear: true,
width: '200px'
});
jQuery('#discount_code').select2({
placeholder: '<?php esc_html_e( 'All Codes', 'paid-memberships-pro' ); ?>',
allowClear: true,
width: '200px'
});
});
</script>
<label for="show_parts" class="screen-reader-text"><?php esc_html_e( 'Select report data to include', 'paid-memberships-pro' ); ?></label>
<select id="show_parts" name="show_parts">
<option value='new_renewals' <?php selected( $new_renewals, 'new_renewals' ); ?> ><?php esc_html_e( 'Show New and Renewals', 'paid-memberships-pro' ); ?></option>
<option value='only_new' <?php selected( $new_renewals, 'only_new' ); ?> ><?php esc_html_e( 'Show Only New', 'paid-memberships-pro' ); ?></option>
<option value='only_renewals' <?php selected( $new_renewals, 'only_renewals' ); ?> ><?php esc_html_e( 'Show Only Renewals', 'paid-memberships-pro' ); ?></option>
</select>
<input type="hidden" name="page" value="pmpro-reports" />
<input type="hidden" name="report" value="sales" />
<input type="submit" class="button button-primary action" value="<?php esc_attr_e('Generate Report', 'paid-memberships-pro' );?>" />
<br class="clear" />
</div> <!-- end tablenav -->
<input type="hidden" name="page" value="pmpro-reports" />
<input type="hidden" name="report" value="sales" />
<input type="submit" class="button button-primary action" value="<?php esc_attr_e('Generate Report', 'paid-memberships-pro' );?>" />
</div> <!-- end pmpro_report-filters -->
<div class="pmpro_chart_area">
<div id="chart_div"></div>
Expand Down
26 changes: 17 additions & 9 deletions adminpages/sales-csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,28 @@
$year = $thisyear;
}

if ( ! empty( $_REQUEST['level'] ) ) {
$l = intval($_REQUEST['level']);
if( ! empty( $_REQUEST['level'] ) ) {
if ( is_array( $_REQUEST['level'] ) ) {
$l = array_map( 'intval', $_REQUEST['level'] );
} else {
$l = array( intval( $_REQUEST['level'] ) );
}
} else {
$l = "";
$l = array();
}

if ( ! empty( $_REQUEST['discount_code'] ) ) {
$discount_code = intval( $_REQUEST[ 'discount_code' ] );
if( ! empty( $_REQUEST['discount_code'] ) ) {
if ( is_array( $_REQUEST['discount_code'] ) ) {
$discount_code = array_map( 'intval', $_REQUEST['discount_code'] );
} else {
$discount_code = array( intval( $_REQUEST['discount_code'] ) );
}
} else {
$discount_code = '';
$discount_code = array();
}

// Same param hash as found in reports/sales.php.
$param_array = array( $period, $type, $month, $year, $l, $discount_code );
$param_array = array( $period, $type, $month, $year, implode( ',', $l ), implode( ',', $discount_code ) );
$param_hash = md5( implode( ' ', $param_array ) . PMPRO_VERSION );
$sales_data = get_transient( 'pmpro_sales_data_' . $param_hash );

Expand All @@ -69,10 +77,10 @@
$filename .= '_' . $year;
}
if ( ! empty( $l ) ) {
$filename .= "_level" . $l;
$filename .= "_level" . implode( '-', $l );
}
if ( ! empty( $discount_code ) ) {
$filename .= "_" . $discount_code;
$filename .= "_dc" . implode( '-', $discount_code );
}
$filename .= ".csv";
/*
Expand Down
38 changes: 36 additions & 2 deletions css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -3219,21 +3219,26 @@ tr.pmpro_alert {
}

.pmpro_report-filters {
align-items: start;
background-color: #FFF;
border: 1px solid var(--pmpro--border--color);
border-radius: var(--pmpro--border--radius);
box-shadow: var(--pmpro--box-shadow);
display: flex;
flex-direction: column;
flex-wrap: nowrap;
gap: var(--pmpro--spacing--small);
margin: 1em 0;
padding: calc( var(--pmpro--spacing--medium) / 2 );
}

.pmpro_report-filters h3 {
margin: 0 0 .75em 0;
margin: 0;
padding: 0;
}

.pmpro_report-filters .tablenav.top {
align-items: center;
align-items: start;
display: flex;
flex-wrap: wrap;
gap: .5em;
Expand All @@ -3242,6 +3247,35 @@ tr.pmpro_alert {
padding: 0;
}

.pmpro_report-filters .tablenav.top .pmpro_report-filter-text {
line-height: 30px;
}

.pmpro_report-filters .select2-container .select2-selection--multiple {
min-height: auto;
}

.pmpro_report-filters .select2-container--default .select2-selection--multiple {
border-color: #8c8f94;
}

.pmpro_report-filters .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
margin: 0;
}

.pmpro_report-filters .select2-container--default .select2-selection--multiple li.select2-selection__choice {
margin: 3px 3px 0 0;
}

.pmpro_report-filters .select2-container--default .select2-search--inline .select2-search__field {
line-height: 1.4;
min-height: auto;
}

.pmpro_report-filters .select2-container--default .select2-search--inline .select2-search__field::placeholder {
color: #2c3338;
}

/* Reports individual page view styles */
#visits-views-logins-form {
margin-top: var(--pmpro--spacing--medium);
Expand Down

0 comments on commit 2a0b9f0

Please sign in to comment.