Merge pull request woocommerce/woocommerce-admin#566 from woocommerce/add/admin-notices-new-sales-record
Activity Panel: Inbox: New Sales Record Note
This commit is contained in:
commit
bf898e642b
|
@ -0,0 +1,102 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WooCommerce Admin (Dashboard) New Sales Record Note Provider.
|
||||||
|
*
|
||||||
|
* Adds a note to the merchant's inbox when the previous day's sales are a new record.
|
||||||
|
*
|
||||||
|
* @package WooCommerce Admin
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WC_Admin_Notes_New_Sales_Record
|
||||||
|
*/
|
||||||
|
class WC_Admin_Notes_New_Sales_Record {
|
||||||
|
const RECORD_DATE_OPTION_KEY = 'woocommerce_sales_record_date'; // ISO 8601 (YYYY-MM-DD) date.
|
||||||
|
const RECORD_AMOUNT_OPTION_KEY = 'woocommerce_sales_record_amount';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the total of yesterday's sales.
|
||||||
|
*
|
||||||
|
* @param string $date Date for sales to sum (i.e. YYYY-MM-DD).
|
||||||
|
* @return floatval
|
||||||
|
*/
|
||||||
|
public static function sum_sales_for_date( $date ) {
|
||||||
|
$order_query = new WC_Order_Query( array( 'date_created' => $date ) );
|
||||||
|
$orders = $order_query->get_orders();
|
||||||
|
$total = 0;
|
||||||
|
|
||||||
|
foreach ( (array) $orders as $order ) {
|
||||||
|
$total += $order->get_total();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possibly add a sales record note.
|
||||||
|
*/
|
||||||
|
public static function possibly_add_sales_record_note() {
|
||||||
|
$yesterday = date( 'Y-m-d', current_time( 'timestamp', 0 ) - DAY_IN_SECONDS );
|
||||||
|
$total = self::sum_sales_for_date( $yesterday );
|
||||||
|
|
||||||
|
// No sales yesterday? Bail.
|
||||||
|
if ( 0 >= $total ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$record_date = get_option( self::RECORD_DATE_OPTION_KEY, '' );
|
||||||
|
$record_amt = floatval( get_option( self::RECORD_AMOUNT_OPTION_KEY, 0 ) );
|
||||||
|
|
||||||
|
// No previous entry? Just enter what we have and return without generating a note.
|
||||||
|
if ( empty( $record_date ) ) {
|
||||||
|
update_option( self::RECORD_DATE_OPTION_KEY, $yesterday );
|
||||||
|
update_option( self::RECORD_AMOUNT_OPTION_KEY, $total );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, if yesterdays total bested the record, update AND generate a note.
|
||||||
|
if ( $total > $record_amt ) {
|
||||||
|
update_option( self::RECORD_DATE_OPTION_KEY, $yesterday );
|
||||||
|
update_option( self::RECORD_AMOUNT_OPTION_KEY, $total );
|
||||||
|
|
||||||
|
$formatted_yesterday = date( 'F jS', strtotime( $yesterday ) );
|
||||||
|
$formatted_total = html_entity_decode( strip_tags( wc_price( $total ) ) );
|
||||||
|
$formatted_record_date = date( 'F jS', strtotime( $record_date ) );
|
||||||
|
$formatted_record_amt = html_entity_decode( strip_tags( wc_price( $record_amt ) ) );
|
||||||
|
|
||||||
|
$content = sprintf(
|
||||||
|
/* translators: 1 and 4: Date (e.g. October 16th), 2 and 3: Amount (e.g. $160.00) */
|
||||||
|
__( 'Woohoo, %1$s was your record day for sales! Net revenue was %2$s beating the previous record of %3$s set on %4$s.', 'wc-admin' ),
|
||||||
|
$formatted_yesterday,
|
||||||
|
$formatted_total,
|
||||||
|
$formatted_record_amt,
|
||||||
|
$formatted_record_date
|
||||||
|
);
|
||||||
|
|
||||||
|
$content_data = (object) array(
|
||||||
|
'old_record_date' => $record_date,
|
||||||
|
'old_record_amt' => $record_amt,
|
||||||
|
'new_record_date' => $yesterday,
|
||||||
|
'new_record_amt' => $total,
|
||||||
|
);
|
||||||
|
|
||||||
|
$name = 'wc-admin-new-sales-record';
|
||||||
|
// We only want one sales record note at any time in the inbox, so we delete any other first.
|
||||||
|
WC_Admin_Notes::delete_notes_with_name( $name );
|
||||||
|
|
||||||
|
// And now, create our new note.
|
||||||
|
$note = new WC_Admin_Note();
|
||||||
|
$note->set_title( __( 'New sales record!', 'wc-admin' ) );
|
||||||
|
$note->set_content( $content );
|
||||||
|
$note->set_content_data( $content_data );
|
||||||
|
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
|
||||||
|
$note->set_icon( 'trophy' );
|
||||||
|
$note->set_name( $name );
|
||||||
|
$note->set_source( 'wc-admin' );
|
||||||
|
$note->add_action( 'view-report', __( 'View report', 'wc-admin' ), '?page=wc-admin#/analytics' );
|
||||||
|
$note->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,4 +69,18 @@ class WC_Admin_Notes {
|
||||||
$data_store = WC_Data_Store::load( 'admin-note' );
|
$data_store = WC_Data_Store::load( 'admin-note' );
|
||||||
return $data_store->get_notes_count();
|
return $data_store->get_notes_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes admin notes with a given name.
|
||||||
|
*
|
||||||
|
* @param string $name Name to search for.
|
||||||
|
*/
|
||||||
|
public static function delete_notes_with_name( $name ) {
|
||||||
|
$data_store = WC_Data_Store::load( 'admin-note' );
|
||||||
|
$note_ids = $data_store->get_notes_with_name( $name );
|
||||||
|
foreach ( (array) $note_ids as $note_id ) {
|
||||||
|
$note = new WC_Admin_Note( $note_id );
|
||||||
|
$note->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,13 +137,13 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
||||||
*/
|
*/
|
||||||
public function delete( &$note, $args = array() ) {
|
public function delete( &$note, $args = array() ) {
|
||||||
$note_id = $note->get_id();
|
$note_id = $note->get_id();
|
||||||
if ( $note->get_id() ) {
|
if ( $note_id ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
$wpdb->delete( $wpdb->prefix . 'woocommerce_admin_notes', array( 'note_id' => $note_id ) );
|
$wpdb->delete( $wpdb->prefix . 'woocommerce_admin_notes', array( 'note_id' => $note_id ) );
|
||||||
$wpdb->delete( $wpdb->prefix . 'woocommerce_admin_note_actions', array( 'note_id' => $note_id ) );
|
$wpdb->delete( $wpdb->prefix . 'woocommerce_admin_note_actions', array( 'note_id' => $note_id ) );
|
||||||
$note->set_id( null );
|
$note->set_id( null );
|
||||||
}
|
}
|
||||||
do_action( 'woocommerce_trash_note', $id );
|
do_action( 'woocommerce_trash_note', $note_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -205,13 +205,6 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
||||||
public function get_notes( $args = array() ) {
|
public function get_notes( $args = array() ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
// Build the query.
|
|
||||||
$query = "
|
|
||||||
SELECT note_id, title, content
|
|
||||||
FROM {$wpdb->prefix}woocommerce_admin_notes
|
|
||||||
ORDER BY note_id DESC
|
|
||||||
";
|
|
||||||
|
|
||||||
$per_page = isset( $args['per_page'] ) ? intval( $args['per_page'] ) : 10;
|
$per_page = isset( $args['per_page'] ) ? intval( $args['per_page'] ) : 10;
|
||||||
if ( $per_page <= 0 ) {
|
if ( $per_page <= 0 ) {
|
||||||
$per_page = 10;
|
$per_page = 10;
|
||||||
|
@ -225,7 +218,13 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
||||||
$offset = $per_page * ( $page - 1 );
|
$offset = $per_page * ( $page - 1 );
|
||||||
$pagination = sprintf( ' LIMIT %d, %d', $offset, $per_page );
|
$pagination = sprintf( ' LIMIT %d, %d', $offset, $per_page );
|
||||||
|
|
||||||
return $wpdb->get_results( $query . $pagination ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
|
return $wpdb->get_results(
|
||||||
|
$wpdb->prepare(
|
||||||
|
"SELECT note_id, title, content FROM {$wpdb->prefix}woocommerce_admin_notes ORDER BY note_id DESC LIMIT %d, %d",
|
||||||
|
$offset,
|
||||||
|
$per_page
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -235,14 +234,24 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
||||||
*/
|
*/
|
||||||
public function get_notes_count() {
|
public function get_notes_count() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
// phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
|
||||||
|
return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_admin_notes" );
|
||||||
|
}
|
||||||
|
|
||||||
// Build the query.
|
/**
|
||||||
$query = "
|
* Find all the notes with a given name.
|
||||||
SELECT COUNT(*)
|
*
|
||||||
FROM {$wpdb->prefix}woocommerce_admin_notes
|
* @param string $name Name to search for.
|
||||||
";
|
* @return array An array of matching note ids.
|
||||||
|
*/
|
||||||
return $wpdb->get_var( $query ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
|
public function get_notes_with_name( $name ) {
|
||||||
|
global $wpdb;
|
||||||
|
return $wpdb->get_col(
|
||||||
|
$wpdb->prepare(
|
||||||
|
"SELECT note_id FROM {$wpdb->prefix}woocommerce_admin_notes WHERE name = %s ORDER BY note_id ASC",
|
||||||
|
$name
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,14 @@ function dependencies_satisfied() {
|
||||||
&& class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.5', '>' );
|
&& class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.5', '>' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Daily events to run.
|
||||||
|
*/
|
||||||
|
function do_wc_admin_daily() {
|
||||||
|
WC_Admin_Notes_New_Sales_Record::possibly_add_sales_record_note();
|
||||||
|
}
|
||||||
|
add_action( 'wc_admin_daily', 'do_wc_admin_daily' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates wc-admin plugin when installed.
|
* Activates wc-admin plugin when installed.
|
||||||
*/
|
*/
|
||||||
|
@ -59,19 +67,30 @@ function activate_wc_admin_plugin() {
|
||||||
|
|
||||||
WC_Admin_Api_Init::install();
|
WC_Admin_Api_Init::install();
|
||||||
|
|
||||||
|
if ( ! wp_next_scheduled( 'wc_admin_daily' ) ) {
|
||||||
|
wp_schedule_event( time(), 'daily', 'wc_admin_daily' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
register_activation_hook( WC_ADMIN_PLUGIN_FILE, 'activate_wc_admin_plugin' );
|
register_activation_hook( WC_ADMIN_PLUGIN_FILE, 'activate_wc_admin_plugin' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deactivate wc-admin plugin if dependencies not satisfied.
|
* Deactivate wc-admin plugin if dependencies not satisfied.
|
||||||
*/
|
*/
|
||||||
function deactivate_wc_admin_plugin() {
|
function possibly_deactivate_wc_admin_plugin() {
|
||||||
if ( ! dependencies_satisfied() ) {
|
if ( ! dependencies_satisfied() ) {
|
||||||
deactivate_plugins( plugin_basename( WC_ADMIN_PLUGIN_FILE ) );
|
deactivate_plugins( plugin_basename( WC_ADMIN_PLUGIN_FILE ) );
|
||||||
unset( $_GET['activate'] );
|
unset( $_GET['activate'] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add_action( 'admin_init', 'deactivate_wc_admin_plugin' );
|
add_action( 'admin_init', 'possibly_deactivate_wc_admin_plugin' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On deactivating the wc-admin plugin.
|
||||||
|
*/
|
||||||
|
function deactivate_wc_admin_plugin() {
|
||||||
|
wp_clear_scheduled_hook( 'wc_admin_daily' );
|
||||||
|
}
|
||||||
|
register_deactivation_hook( WC_ADMIN_PLUGIN_FILE, 'deactivate_wc_admin_plugin' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the plugin, only if we can detect both Gutenberg and WooCommerce
|
* Set up the plugin, only if we can detect both Gutenberg and WooCommerce
|
||||||
|
@ -93,5 +112,8 @@ function wc_admin_plugins_loaded() {
|
||||||
|
|
||||||
// Create the Admin pages.
|
// Create the Admin pages.
|
||||||
require_once dirname( __FILE__ ) . '/lib/admin.php';
|
require_once dirname( __FILE__ ) . '/lib/admin.php';
|
||||||
|
|
||||||
|
// Admin note providers.
|
||||||
|
require_once dirname( __FILE__ ) . '/includes/class-wc-admin-notes-new-sales-record.php';
|
||||||
}
|
}
|
||||||
add_action( 'plugins_loaded', 'wc_admin_plugins_loaded' );
|
add_action( 'plugins_loaded', 'wc_admin_plugins_loaded' );
|
||||||
|
|
Loading…
Reference in New Issue