has_status( self::STATUS ) ) {
return;
}
$product = $item->get_product();
$release = $product ? Preorvo_Product::release_time( $product ) : (int) $item->get_meta( Preorvo_Product::META_RELEASE );
if ( $release <= time() ) {
return;
}
/* translators: %s: release date */
$text = sprintf( __( 'Pre-order: ships from %s', 'preorvo' ), Preorvo_Product::format_date( $release ) );
echo $plain_text ? "\n" . esc_html( $text ) : '
' . esc_html( $text ) . '';
}
public static function status_style() {
wp_register_style( 'preorvo-admin', false, array(), PREORVO_VERSION );
wp_enqueue_style( 'preorvo-admin' );
wp_add_inline_style( 'preorvo-admin', '.order-status.status-' . sanitize_html_class( self::STATUS ) . '{background:#e5d4f0;color:#5b2c86}' );
}
public static function register_status() {
register_post_status( 'wc-' . self::STATUS, array(
'label' => _x( 'Pre-ordered', 'Order status', 'preorvo' ),
'public' => false,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
/* translators: %s: number of orders */
'label_count' => _n_noop( 'Pre-ordered (%s)', 'Pre-ordered (%s)', 'preorvo' ),
) );
}
public static function add_status_label( $statuses ) {
$result = array();
foreach ( $statuses as $key => $label ) {
$result[ $key ] = $label;
if ( 'wc-processing' === $key ) {
$result[ 'wc-' . self::STATUS ] = _x( 'Pre-ordered', 'Order status', 'preorvo' );
}
}
if ( ! isset( $result[ 'wc-' . self::STATUS ] ) ) {
$result[ 'wc-' . self::STATUS ] = _x( 'Pre-ordered', 'Order status', 'preorvo' );
}
return $result;
}
public static function add_paid_status( $statuses ) {
$statuses[] = self::STATUS;
return $statuses;
}
/**
* When the order may ship: the latest release date among its pre-order items, or 0 if nothing is waiting.
*/
public static function release_time( $order ) {
if ( 'yes' === $order->get_meta( self::META_RELEASED ) ) {
return 0;
}
$latest = 0;
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( $product ) {
$release = Preorvo_Product::release_time( $product );
} else {
// Product deleted: fall back to the date frozen at checkout.
$stored = (int) $item->get_meta( Preorvo_Product::META_RELEASE );
$release = $stored > time() ? $stored : 0;
}
$latest = max( $latest, $release );
}
return $latest;
}
public static function payment_complete_status( $status, $order_id, $order = null ) {
$order = $order ? $order : wc_get_order( $order_id );
return ( $order && self::release_time( $order ) ) ? self::STATUS : $status;
}
public static function guard( $order ) {
$changes = $order->get_changes();
if ( ! isset( $changes['status'] ) || ! in_array( $order->get_status(), array( 'processing', 'completed' ), true ) ) {
return;
}
$release = self::release_time( $order );
if ( ! $release ) {
return;
}
$order->set_status( self::STATUS );
self::drop_noop_transition( $order );
// A separate note: passed to set_status() it would also get WooCommerce's "changed from X to X" line.
if ( $order->get_id() ) {
$order->add_order_note(
sprintf(
/* translators: 1: blocked status, 2: release date */
__( 'Preorvo kept this order on hold: it was set to "%1$s" before the release date (%2$s). Use "Release pre-order now" to ship it early on purpose.', 'preorvo' ),
wc_get_order_status_name( $changes['status'] ),
Preorvo_Product::format_date( $release )
)
);
}
}
/**
* When the guard puts an order back where it started, WooCommerce would still log
* "Order status changed from Pre-ordered to Pre-ordered". Forget that empty transition.
*/
private static function drop_noop_transition( $order ) {
if ( ! property_exists( 'WC_Order', 'status_transition' ) ) {
return;
}
$drop = function () {
if ( is_array( $this->status_transition ) && $this->status_transition['from'] === $this->status_transition['to'] ) {
$this->status_transition = false;
}
};
\Closure::bind( $drop, $order, 'WC_Order' )();
}
public static function on_preorder_status( $order_id, $order ) {
// Some gateways (cash on delivery, manual edits) never call payment_complete(), so stock is reduced here too.
wc_maybe_reduce_stock_levels( $order_id );
}
public static function add_release_action( $actions, $order = null ) {
if ( $order && $order->has_status( self::STATUS ) ) {
$actions['preorvo_release_now'] = __( 'Release pre-order now', 'preorvo' );
}
return $actions;
}
public static function release_now( $order ) {
Preorvo_Release::release( $order, __( 'Pre-order released manually.', 'preorvo' ) );
}
}