get_results( "SELECT * FROM {$wpdb->prefix}wpdd_creator_earnings WHERE payout_status = 'pending' AND available_at <= NOW() AND available_at IS NOT NULL" ); if (empty($pending_earnings)) { return; // Nothing to process } // Update all pending earnings to available $updated = $wpdb->query( "UPDATE {$wpdb->prefix}wpdd_creator_earnings SET payout_status = 'available' WHERE payout_status = 'pending' AND available_at <= NOW() AND available_at IS NOT NULL" ); if ($updated > 0) { // Log the processing error_log("WPDD: Processed $updated pending earnings to available status"); // Update creator balances for affected creators $affected_creators = $wpdb->get_col( "SELECT DISTINCT creator_id FROM {$wpdb->prefix}wpdd_creator_earnings WHERE payout_status = 'available' AND available_at <= NOW()" ); foreach ($affected_creators as $creator_id) { // Trigger balance recalculation $current_balance = WPDD_Creator::get_creator_balance($creator_id); update_user_meta($creator_id, 'wpdd_creator_balance', $current_balance); } } } /** * Manually process a specific earning (for admin override) */ public static function release_earning_immediately($earning_id) { global $wpdb; $result = $wpdb->update( $wpdb->prefix . 'wpdd_creator_earnings', array( 'payout_status' => 'available', 'available_at' => current_time('mysql') ), array( 'id' => $earning_id, 'payout_status' => 'pending' ), array('%s', '%s'), array('%d', '%s') ); if ($result) { // Get the creator and update their balance $earning = $wpdb->get_row($wpdb->prepare( "SELECT creator_id FROM {$wpdb->prefix}wpdd_creator_earnings WHERE id = %d", $earning_id )); if ($earning) { $current_balance = WPDD_Creator::get_creator_balance($earning->creator_id); update_user_meta($earning->creator_id, 'wpdd_creator_balance', $current_balance); } } return $result > 0; } /** * Cancel/refund a specific earning (for order cancellations) */ public static function cancel_earning($earning_id, $reason = 'Order cancelled/refunded') { global $wpdb; // Get the earning details $earning = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpdd_creator_earnings WHERE id = %d", $earning_id )); if (!$earning) { return false; } // Only cancel if not already paid out if ($earning->payout_status === 'paid') { return false; // Cannot cancel paid earnings } // Update to cancelled status $result = $wpdb->update( $wpdb->prefix . 'wpdd_creator_earnings', array( 'payout_status' => 'cancelled', 'available_at' => null ), array('id' => $earning_id), array('%s', '%s'), array('%d') ); if ($result) { // Log the cancellation $wpdb->insert( $wpdb->prefix . 'wpdd_balance_adjustments', array( 'creator_id' => $earning->creator_id, 'adjustment_type' => 'subtract', 'amount' => $earning->creator_earning, 'previous_balance' => WPDD_Creator::get_creator_balance($earning->creator_id), 'new_balance' => WPDD_Creator::get_creator_balance($earning->creator_id) - $earning->creator_earning, 'reason' => $reason . ' (Order #' . $earning->order_id . ')', 'adjusted_by' => get_current_user_id(), 'created_at' => current_time('mysql') ), array('%d', '%s', '%f', '%f', '%f', '%s', '%d', '%s') ); // Update creator balance $current_balance = WPDD_Creator::get_creator_balance($earning->creator_id); update_user_meta($earning->creator_id, 'wpdd_creator_balance', $current_balance - $earning->creator_earning); } return $result > 0; } /** * Get earnings summary for a creator */ public static function get_earnings_summary($creator_id) { global $wpdb; $summary = $wpdb->get_row($wpdb->prepare( "SELECT COUNT(*) as total_earnings, SUM(CASE WHEN payout_status = 'pending' THEN creator_earning ELSE 0 END) as pending_amount, SUM(CASE WHEN payout_status = 'available' THEN creator_earning ELSE 0 END) as available_amount, SUM(CASE WHEN payout_status = 'paid' THEN creator_earning ELSE 0 END) as paid_amount, SUM(CASE WHEN payout_status = 'cancelled' THEN creator_earning ELSE 0 END) as cancelled_amount, SUM(creator_earning) as total_amount FROM {$wpdb->prefix}wpdd_creator_earnings WHERE creator_id = %d", $creator_id )); return $summary; } }