prefix . 'woonoow_referrals'; // Get the order to determine the reason $order = wc_get_order($order_id); $reason = 'order_cancelled'; if ($order) { $status = $order->get_status(); $reason = 'order_' . $status; } // Find pending or approved referral $referral = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $referrals_table WHERE order_id = %d AND status IN ('pending', 'approved')", $order_id )); if ($referral) { // If was already approved, this is a clawback - decrease affiliate earnings if ($referral->status === 'approved') { $affiliates_table = $wpdb->prefix . 'woonoow_affiliates'; $wpdb->query($wpdb->prepare( "UPDATE $affiliates_table SET total_earnings = total_earnings - %f WHERE id = %d", $referral->commission_amount, $referral->affiliate_id )); } // Update status to rejected with reason $wpdb->update( $referrals_table, [ 'status' => 'rejected', 'cancelled_reason' => $reason, 'cancelled_at' => current_time('mysql') ], ['id' => $referral->id] ); // Unschedule action if action scheduler exists if (function_exists('as_unschedule_all_actions')) { as_unschedule_all_actions('woonoow_approve_referral', ['referral_id' => $referral->id], 'woonoow_affiliate'); } } } /** * Handle order completion - check if referral should be approved */ public static function handle_order_completed($order_id) { global $wpdb; $referrals_table = $wpdb->prefix . 'woonoow_referrals'; // Find pending referral for this order $referral = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $referrals_table WHERE order_id = %d AND status = 'pending'", $order_id )); if (!$referral) return; // Check if holding period is 0 (immediate approval on completion) $holding_period = (int) get_option('woonoow_affiliate_holding_period', 14); if ($holding_period === 0) { // Immediate approval self::auto_approve_referral($referral->id); } else { // If order was completed BEFORE the scheduled action time, approve now // Otherwise, the scheduled action will approve later // Check if the scheduled action time has already passed $approval_time = strtotime($referral->created_at) + ($holding_period * DAY_IN_SECONDS); if (time() >= $approval_time) { self::auto_approve_referral($referral->id); } // If not, the scheduled Action Scheduler job will handle it } // Cancel the scheduled auto-approval since we're handling it now if (function_exists('as_unschedule_all_actions')) { as_unschedule_all_actions('woonoow_approve_referral', ['referral_id' => $referral->id], 'woonoow_affiliate'); } } /** * Handle HPOS order status change */ public static function handle_hpos_status_changed($order_id, $from_status, $to_status, $order) { if ($to_status === 'completed') { self::handle_order_completed($order_id); } } /** * Handle order update (HPOS compatible) */ public static function handle_order_updated($order_id, $order) { if (!$order) return; // Check if order was just completed $status = $order->get_status(); if ($status === 'completed') { self::handle_order_completed($order_id); } } /** * Handle order deletion (permanent delete or trash) */ public static function handle_order_deleted($order_id) { // Check if this is a WooCommerce order $order = wc_get_order($order_id); if (!$order) return; // Only process shop orders $post_type = get_post_type($order_id); if ($post_type !== 'shop_order') return; global $wpdb; $referrals_table = $wpdb->prefix . 'woonoow_referrals'; // Find any referral for this order $referral = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $referrals_table WHERE order_id = %d", $order_id )); if ($referral) { // If was already approved, this is a clawback - decrease affiliate earnings if ($referral->status === 'approved') { $affiliates_table = $wpdb->prefix . 'woonoow_affiliates'; $wpdb->query($wpdb->prepare( "UPDATE $affiliates_table SET total_earnings = total_earnings - %f WHERE id = %d", $referral->commission_amount, $referral->affiliate_id )); } // Mark as rejected with "order_deleted" reason $wpdb->update( $referrals_table, [ 'status' => 'rejected', 'cancelled_reason' => 'order_deleted', 'cancelled_at' => current_time('mysql') ], ['id' => $referral->id] ); // Unschedule any pending approval action if (function_exists('as_unschedule_all_actions')) { as_unschedule_all_actions('woonoow_approve_referral', ['referral_id' => $referral->id], 'woonoow_affiliate'); } } } /** * Action Scheduler callback for auto-approving a referral after the holding period */ public static function auto_approve_referral($referral_id) { global $wpdb; $referrals_table = $wpdb->prefix . 'woonoow_referrals'; $affiliates_table = $wpdb->prefix . 'woonoow_affiliates'; // Find pending referral $referral = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $referrals_table WHERE id = %d AND status = 'pending'", $referral_id )); if (!$referral) return; // Already processed or deleted // Double check order status $order = wc_get_order($referral->order_id); if (!$order || in_array($order->get_status(), ['refunded', 'cancelled', 'failed'])) { self::handle_order_cancelled($referral->order_id); return; } // Approve referral $wpdb->update( $referrals_table, [ 'status' => 'approved', 'approved_at' => current_time('mysql') ], ['id' => $referral_id] ); // Update Affiliate totals $wpdb->query($wpdb->prepare( "UPDATE $affiliates_table SET total_referrals = total_referrals + 1, total_earnings = total_earnings + %f WHERE id = %d", $referral->commission_amount, $referral->affiliate_id )); } }