Add total payments volume rule processor for inbox notifications (#33192)
* Add method to get total sales for a timeframe * Add total payments volume rule processor * Use start and end dates for total sales method * Add method to get start and end dates from timeframe * Update processor rule to use timeframes * Fix up method calls * Add tests for timeframes * Add tests around getting total sales by date * Add changelog entry * Use revenue query instead of custom query for total sales * Update since tag on hook
This commit is contained in:
parent
7de6d18b2e
commit
bec9e92b32
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: enhancement
|
||||
|
||||
Add total payments volume rule processor for inbox notifications #33192
|
|
@ -353,6 +353,11 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
|||
|
||||
if ( $is_variation ) {
|
||||
$variation = wc_get_product( $product_data['id'] );
|
||||
/**
|
||||
* Used to determine the separator for products and their variations titles.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
$separator = apply_filters( 'woocommerce_product_variation_title_attributes_separator', ' - ', $variation );
|
||||
|
||||
if ( false === strpos( $product_data['name'], $separator ) ) {
|
||||
|
|
|
@ -631,4 +631,80 @@ class TimeInterval {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dates from a timeframe string.
|
||||
*
|
||||
* @param int $timeframe Timeframe to use. One of: last_week|last_month|last_quarter|last_6_months|last_year.
|
||||
* @param DateTime|null $current_date DateTime of current date to compare.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_timeframe_dates( $timeframe, $current_date = null ) {
|
||||
if ( ! $current_date ) {
|
||||
$current_date = new \DateTime();
|
||||
}
|
||||
$current_year = $current_date->format( 'Y' );
|
||||
$current_month = $current_date->format( 'm' );
|
||||
|
||||
if ( 'last_week' === $timeframe ) {
|
||||
return array(
|
||||
'start' => $current_date->modify( 'last week monday' )->format( 'Y-m-d 00:00:00' ),
|
||||
'end' => $current_date->modify( 'this sunday' )->format( 'Y-m-d 23:59:59' ),
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'last_month' === $timeframe ) {
|
||||
return array(
|
||||
'start' => $current_date->modify( 'first day of previous month' )->format( 'Y-m-d 00:00:00' ),
|
||||
'end' => $current_date->modify( 'last day of this month' )->format( 'Y-m-d 23:59:59' ),
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'last_quarter' === $timeframe ) {
|
||||
switch ( $current_month ) {
|
||||
case $current_month >= 1 && $current_month <= 3:
|
||||
return array(
|
||||
'start' => ( $current_year - 1 ) . '-10-01 00:00:00',
|
||||
'end' => ( $current_year - 1 ) . '-12-31 23:59:59',
|
||||
);
|
||||
case $current_month >= 4 && $current_month <= 6:
|
||||
return array(
|
||||
'start' => $current_year . '-01-01 00:00:00',
|
||||
'end' => $current_year . '-03-31 23:59:59',
|
||||
);
|
||||
case $current_month >= 7 && $current_month <= 9:
|
||||
return array(
|
||||
'start' => $current_year . '-04-01 00:00:00',
|
||||
'end' => $current_year . '-06-30 23:59:59',
|
||||
);
|
||||
case $current_month >= 10 && $current_month <= 12:
|
||||
return array(
|
||||
'start' => $current_year . '-07-01 00:00:00',
|
||||
'end' => $current_year . '-09-31 23:59:59',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'last_6_months' === $timeframe ) {
|
||||
if ( $current_month >= 1 && $current_month <= 6 ) {
|
||||
return array(
|
||||
'start' => ( $current_year - 1 ) . '-07-01 00:00:00',
|
||||
'end' => ( $current_year - 1 ) . '-12-31 23:59:59',
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'start' => $current_year . '-01-01 00:00:00',
|
||||
'end' => $current_year . '-06-30 23:59:59',
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'last_year' === $timeframe ) {
|
||||
return array(
|
||||
'start' => ( $current_year - 1 ) . '-01-01 00:00:00',
|
||||
'end' => ( $current_year - 1 ) . '-12-31 23:59:59',
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@ class GetRuleProcessor {
|
|||
return new OptionRuleProcessor();
|
||||
case 'wca_updated':
|
||||
return new WooCommerceAdminUpdatedRuleProcessor();
|
||||
case 'total_payments_value':
|
||||
return new TotalPaymentsVolumeProcessor();
|
||||
}
|
||||
|
||||
return new FailRuleProcessor();
|
||||
|
|
|
@ -409,6 +409,22 @@ actioned.
|
|||
}
|
||||
```
|
||||
|
||||
### Total Payments Value
|
||||
This passes when the total value of all payments for a given timeframe
|
||||
compared to the provided value pass the operation test.
|
||||
|
||||
`timeframe` can be one of `last_week`, `last_month`, `last_quarter`, `last_6_months`, `last_year`
|
||||
|
||||
```
|
||||
{
|
||||
"type": "total_payments_value",
|
||||
"days": "last_month",
|
||||
"value": "actioned",
|
||||
"operation": ">"
|
||||
}
|
||||
```
|
||||
`timeframe`, `value`, and `operation` are all required.
|
||||
|
||||
### Option
|
||||
This passes when the option value matches the value using the operation.
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
/**
|
||||
* Rule processor that passes when a store's payments volume exceeds a provided amount.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\API\Reports\Revenue\Query as RevenueQuery;
|
||||
use Automattic\WooCommerce\Admin\API\Reports\TimeInterval;
|
||||
|
||||
/**
|
||||
* Rule processor that passes when a store's payments volume exceeds a provided amount.
|
||||
*/
|
||||
class TotalPaymentsVolumeProcessor implements RuleProcessorInterface {
|
||||
/**
|
||||
* Compare against the store's total payments volume.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$dates = TimeInterval::get_timeframe_dates( $rule->timeframe );
|
||||
$reports_revenue = new RevenueQuery(
|
||||
array(
|
||||
'before' => $dates['end'],
|
||||
'after' => $dates['start'],
|
||||
'interval' => 'year',
|
||||
'fields' => array( 'total_sales' ),
|
||||
)
|
||||
);
|
||||
$report_data = $reports_revenue->get_data();
|
||||
$value = $report_data->totals->total_sales;
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$value,
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
$allowed_timeframes = array(
|
||||
'last_week',
|
||||
'last_month',
|
||||
'last_quarter',
|
||||
'last_6_months',
|
||||
'last_year',
|
||||
);
|
||||
|
||||
if ( ! isset( $rule->timeframe ) || ! in_array( $rule->timeframe, $allowed_timeframes, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1013,4 +1013,107 @@ class WC_Admin_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case {
|
|||
TimeInterval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00', '2019-01-15T00:00:00' ), null, 'param' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we get the correct start and end times for "last_week" timeframes.
|
||||
*/
|
||||
public function test_timeframes_last_week() {
|
||||
$datetime = new DateTime( '2022-05-26' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_week', $datetime );
|
||||
|
||||
$this->assertEquals( '2022-05-16 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2022-05-22 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2022-05-16' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_week', $datetime );
|
||||
|
||||
$this->assertEquals( '2022-05-09 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2022-05-15 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2022-01-02' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_week', $datetime );
|
||||
|
||||
$this->assertEquals( '2021-12-20 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2021-12-26 23:59:59', $dates['end'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we get the correct start and end times for "last_month" timeframes.
|
||||
*/
|
||||
public function test_timeframes_last_month() {
|
||||
$datetime = new DateTime( '2022-05-26' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_month', $datetime );
|
||||
|
||||
$this->assertEquals( '2022-04-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2022-04-30 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2021-01-12' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_month', $datetime );
|
||||
|
||||
$this->assertEquals( '2020-12-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2020-12-31 23:59:59', $dates['end'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we get the correct start and end times for "last_quarter" timeframes.
|
||||
*/
|
||||
public function test_timeframes_last_quarter() {
|
||||
$datetime = new DateTime( '2022-05-26' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_quarter', $datetime );
|
||||
|
||||
$this->assertEquals( '2022-01-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2022-03-31 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2022-01-12' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_quarter', $datetime );
|
||||
|
||||
$this->assertEquals( '2021-10-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2021-12-31 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2022-07-18' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_quarter', $datetime );
|
||||
|
||||
$this->assertEquals( '2022-04-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2022-06-30 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2022-11-07' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_quarter', $datetime );
|
||||
|
||||
$this->assertEquals( '2022-07-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2022-09-31 23:59:59', $dates['end'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we get the correct start and end times for "last_6_months" timeframes.
|
||||
*/
|
||||
public function test_timeframes_last_6_months() {
|
||||
$datetime = new DateTime( '2022-05-26' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_6_months', $datetime );
|
||||
|
||||
$this->assertEquals( '2021-07-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2021-12-31 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2021-09-12' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_6_months', $datetime );
|
||||
|
||||
$this->assertEquals( '2021-01-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2021-06-30 23:59:59', $dates['end'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we get the correct start and end times for "last_year" timeframes.
|
||||
*/
|
||||
public function test_timeframes_last_year() {
|
||||
$datetime = new DateTime( '2022-05-26' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_year', $datetime );
|
||||
|
||||
$this->assertEquals( '2021-01-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2021-12-31 23:59:59', $dates['end'] );
|
||||
|
||||
$datetime = new DateTime( '2021-09-12' );
|
||||
$dates = TimeInterval::get_timeframe_dates( 'last_year', $datetime );
|
||||
|
||||
$this->assertEquals( '2020-01-01 00:00:00', $dates['start'] );
|
||||
$this->assertEquals( '2020-12-31 23:59:59', $dates['end'] );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue