Adding more functionality
This commit is contained in:
@@ -12,6 +12,7 @@ class WPDD_Admin {
|
||||
add_action('manage_wpdd_product_posts_custom_column', array(__CLASS__, 'render_product_columns'), 10, 2);
|
||||
add_filter('manage_edit-wpdd_product_sortable_columns', array(__CLASS__, 'make_columns_sortable'));
|
||||
add_action('pre_get_posts', array(__CLASS__, 'sort_products_by_column'));
|
||||
add_action('pre_get_posts', array(__CLASS__, 'filter_creator_products'));
|
||||
add_action('admin_init', array(__CLASS__, 'handle_admin_actions'));
|
||||
|
||||
// Initialize admin payouts
|
||||
@@ -21,41 +22,70 @@ class WPDD_Admin {
|
||||
}
|
||||
|
||||
public static function add_admin_menus() {
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Orders', 'wp-digital-download'),
|
||||
__('Orders', 'wp-digital-download'),
|
||||
'wpdd_manage_orders',
|
||||
'wpdd-orders',
|
||||
array(__CLASS__, 'render_orders_page')
|
||||
);
|
||||
// Show different menus based on user role
|
||||
$user = wp_get_current_user();
|
||||
$is_creator = in_array('wpdd_creator', (array) $user->roles);
|
||||
$is_admin = current_user_can('manage_options');
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Reports', 'wp-digital-download'),
|
||||
__('Reports', 'wp-digital-download'),
|
||||
'wpdd_view_reports',
|
||||
'wpdd-reports',
|
||||
array(__CLASS__, 'render_reports_page')
|
||||
);
|
||||
if ($is_admin) {
|
||||
// Full admin menus
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Orders', 'wp-digital-download'),
|
||||
__('Orders', 'wp-digital-download'),
|
||||
'wpdd_manage_orders',
|
||||
'wpdd-orders',
|
||||
array(__CLASS__, 'render_orders_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Reports', 'wp-digital-download'),
|
||||
__('Reports', 'wp-digital-download'),
|
||||
'wpdd_view_reports',
|
||||
'wpdd-reports',
|
||||
array(__CLASS__, 'render_reports_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Customers', 'wp-digital-download'),
|
||||
__('Customers', 'wp-digital-download'),
|
||||
'wpdd_manage_orders',
|
||||
'wpdd-customers',
|
||||
array(__CLASS__, 'render_customers_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Shortcodes', 'wp-digital-download'),
|
||||
__('Shortcodes', 'wp-digital-download'),
|
||||
'edit_wpdd_products',
|
||||
'wpdd-shortcodes',
|
||||
array(__CLASS__, 'render_shortcodes_page')
|
||||
);
|
||||
}
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Customers', 'wp-digital-download'),
|
||||
__('Customers', 'wp-digital-download'),
|
||||
'wpdd_manage_orders',
|
||||
'wpdd-customers',
|
||||
array(__CLASS__, 'render_customers_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('Shortcodes', 'wp-digital-download'),
|
||||
__('Shortcodes', 'wp-digital-download'),
|
||||
'edit_wpdd_products',
|
||||
'wpdd-shortcodes',
|
||||
array(__CLASS__, 'render_shortcodes_page')
|
||||
);
|
||||
if ($is_creator || $is_admin) {
|
||||
// Creator-specific menus
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('My Sales', 'wp-digital-download'),
|
||||
__('My Sales', 'wp-digital-download'),
|
||||
'wpdd_view_own_sales',
|
||||
'wpdd-creator-sales',
|
||||
array(__CLASS__, 'render_creator_sales_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'edit.php?post_type=wpdd_product',
|
||||
__('My Payouts', 'wp-digital-download'),
|
||||
__('My Payouts', 'wp-digital-download'),
|
||||
'wpdd_view_own_sales',
|
||||
'wpdd-creator-payouts',
|
||||
array(__CLASS__, 'render_creator_payouts_page')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function add_product_columns($columns) {
|
||||
@@ -917,4 +947,289 @@ class WPDD_Admin {
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function filter_creator_products($query) {
|
||||
if (!is_admin() || !$query->is_main_query()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($_GET['post_type']) || $_GET['post_type'] !== 'wpdd_product') {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = wp_get_current_user();
|
||||
$is_creator = in_array('wpdd_creator', (array) $user->roles);
|
||||
$is_admin = current_user_can('manage_options');
|
||||
|
||||
// Only filter for creators, not admins
|
||||
if ($is_creator && !$is_admin) {
|
||||
$query->set('author', get_current_user_id());
|
||||
}
|
||||
}
|
||||
|
||||
public static function render_creator_sales_page() {
|
||||
global $wpdb;
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$currency = get_option('wpdd_currency', 'USD');
|
||||
$commission_rate = floatval(get_option('wpdd_commission_rate', 0));
|
||||
|
||||
// Get creator's sales data
|
||||
$sales = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT o.*, p.post_title as product_name,
|
||||
(o.total * %f / 100) as platform_fee,
|
||||
(o.total * (100 - %f) / 100) as creator_earning
|
||||
FROM {$wpdb->prefix}wpdd_orders o
|
||||
INNER JOIN {$wpdb->posts} p ON o.product_id = p.ID
|
||||
WHERE p.post_author = %d
|
||||
AND o.status = 'completed'
|
||||
ORDER BY o.purchase_date DESC
|
||||
LIMIT 100",
|
||||
$commission_rate,
|
||||
$commission_rate,
|
||||
$user_id
|
||||
));
|
||||
|
||||
// Get totals
|
||||
$total_sales = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT SUM(o.total)
|
||||
FROM {$wpdb->prefix}wpdd_orders o
|
||||
INNER JOIN {$wpdb->posts} p ON o.product_id = p.ID
|
||||
WHERE p.post_author = %d
|
||||
AND o.status = 'completed'",
|
||||
$user_id
|
||||
));
|
||||
|
||||
$total_earnings = $total_sales * (1 - ($commission_rate / 100));
|
||||
$current_balance = WPDD_Creator::get_creator_balance($user_id);
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php _e('My Sales Report', 'wp-digital-download'); ?></h1>
|
||||
|
||||
<div class="wpdd-stats-row" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px;">
|
||||
<div class="wpdd-stat-card" style="background: #fff; padding: 20px; border: 1px solid #ccd0d4; border-radius: 4px;">
|
||||
<h3 style="margin: 0 0 10px; color: #646970;"><?php _e('Total Sales', 'wp-digital-download'); ?></h3>
|
||||
<div style="font-size: 24px; font-weight: bold; color: #1d2327;"><?php echo wpdd_format_price($total_sales, $currency); ?></div>
|
||||
</div>
|
||||
<div class="wpdd-stat-card" style="background: #fff; padding: 20px; border: 1px solid #ccd0d4; border-radius: 4px;">
|
||||
<h3 style="margin: 0 0 10px; color: #646970;"><?php _e('Your Earnings', 'wp-digital-download'); ?></h3>
|
||||
<div style="font-size: 24px; font-weight: bold; color: #1d2327;"><?php echo wpdd_format_price($total_earnings, $currency); ?></div>
|
||||
<small style="color: #646970;"><?php printf(__('After %s%% platform fee', 'wp-digital-download'), $commission_rate); ?></small>
|
||||
</div>
|
||||
<div class="wpdd-stat-card" style="background: #fff; padding: 20px; border: 1px solid #ccd0d4; border-radius: 4px;">
|
||||
<h3 style="margin: 0 0 10px; color: #646970;"><?php _e('Available Balance', 'wp-digital-download'); ?></h3>
|
||||
<div style="font-size: 24px; font-weight: bold; color: #1d2327;"><?php echo wpdd_format_price($current_balance, $currency); ?></div>
|
||||
<small style="color: #646970;"><?php _e('Ready for payout', 'wp-digital-download'); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($sales)) : ?>
|
||||
<div class="wpdd-sales-table">
|
||||
<h2><?php _e('Recent Sales', 'wp-digital-download'); ?></h2>
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Date', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Product', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Customer', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Sale Amount', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Platform Fee', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Your Earning', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Status', 'wp-digital-download'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($sales as $sale) : ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html(date_i18n(get_option('date_format'), strtotime($sale->purchase_date))); ?></td>
|
||||
<td><?php echo esc_html($sale->product_name); ?></td>
|
||||
<td><?php echo esc_html($sale->customer_name); ?></td>
|
||||
<td><?php echo wpdd_format_price($sale->total, $currency); ?></td>
|
||||
<td><?php echo wpdd_format_price($sale->platform_fee, $currency); ?></td>
|
||||
<td><strong><?php echo wpdd_format_price($sale->creator_earning, $currency); ?></strong></td>
|
||||
<td>
|
||||
<span class="wpdd-status-<?php echo esc_attr($sale->status); ?>" style="padding: 2px 8px; border-radius: 3px; font-size: 12px; <?php echo $sale->status === 'completed' ? 'background: #d1e7dd; color: #0f5132;' : 'background: #f8d7da; color: #721c24;'; ?>">
|
||||
<?php echo esc_html(ucfirst($sale->status)); ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div style="background: #fff; padding: 40px; border: 1px solid #ccd0d4; border-radius: 4px; text-align: center;">
|
||||
<h3><?php _e('No sales yet', 'wp-digital-download'); ?></h3>
|
||||
<p><?php _e('Once customers purchase your products, your sales data will appear here.', 'wp-digital-download'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function render_creator_payouts_page() {
|
||||
global $wpdb;
|
||||
|
||||
if (isset($_POST['request_payout']) && wp_verify_nonce($_POST['wpdd_nonce'], 'wpdd_request_payout')) {
|
||||
self::handle_payout_request();
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$currency = get_option('wpdd_currency', 'USD');
|
||||
$current_balance = WPDD_Creator::get_creator_balance($user_id);
|
||||
$paypal_email = get_user_meta($user_id, 'wpdd_paypal_email', true);
|
||||
$threshold = floatval(get_option('wpdd_payout_threshold', 0));
|
||||
|
||||
// Get payout history
|
||||
$payouts = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wpdd_payouts
|
||||
WHERE creator_id = %d
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 50",
|
||||
$user_id
|
||||
));
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php _e('My Payouts', 'wp-digital-download'); ?></h1>
|
||||
|
||||
<?php if (isset($_GET['message']) && $_GET['message'] === 'payout_requested') : ?>
|
||||
<div class="notice notice-success is-dismissible">
|
||||
<p><?php _e('Payout request submitted successfully!', 'wp-digital-download'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="wpdd-payout-request" style="background: #fff; padding: 20px; border: 1px solid #ccd0d4; border-radius: 4px; margin-bottom: 30px;">
|
||||
<h2><?php _e('Request Payout', 'wp-digital-download'); ?></h2>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 2fr; gap: 20px; align-items: start;">
|
||||
<div>
|
||||
<h3><?php _e('Current Balance', 'wp-digital-download'); ?></h3>
|
||||
<div style="font-size: 32px; font-weight: bold; color: #1d2327; margin: 10px 0;">
|
||||
<?php echo wpdd_format_price($current_balance, $currency); ?>
|
||||
</div>
|
||||
<?php if ($threshold > 0) : ?>
|
||||
<p style="color: #646970; margin: 0;">
|
||||
<?php printf(__('Minimum for automatic payout: %s', 'wp-digital-download'), wpdd_format_price($threshold, $currency)); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<?php if (empty($paypal_email)) : ?>
|
||||
<div class="notice notice-warning" style="margin: 0;">
|
||||
<p><?php _e('Please add your PayPal email in your profile before requesting a payout.', 'wp-digital-download'); ?></p>
|
||||
<p><a href="<?php echo esc_url(get_edit_profile_url($user_id)); ?>" class="button"><?php _e('Edit Profile', 'wp-digital-download'); ?></a></p>
|
||||
</div>
|
||||
<?php elseif ($current_balance <= 0) : ?>
|
||||
<div class="notice notice-info" style="margin: 0;">
|
||||
<p><?php _e('No balance available for payout.', 'wp-digital-download'); ?></p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<form method="post">
|
||||
<?php wp_nonce_field('wpdd_request_payout', 'wpdd_nonce'); ?>
|
||||
<p><?php _e('PayPal Email:', 'wp-digital-download'); ?> <strong><?php echo esc_html($paypal_email); ?></strong></p>
|
||||
<p><?php _e('Requesting a payout will notify administrators to process your payment.', 'wp-digital-download'); ?></p>
|
||||
<button type="submit" name="request_payout" class="button button-primary">
|
||||
<?php printf(__('Request Payout of %s', 'wp-digital-download'), wpdd_format_price($current_balance, $currency)); ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($payouts)) : ?>
|
||||
<div class="wpdd-payout-history">
|
||||
<h2><?php _e('Payout History', 'wp-digital-download'); ?></h2>
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Date Requested', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Amount', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('PayPal Email', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Status', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Transaction ID', 'wp-digital-download'); ?></th>
|
||||
<th><?php _e('Processed Date', 'wp-digital-download'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($payouts as $payout) : ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html(date_i18n(get_option('date_format'), strtotime($payout->created_at))); ?></td>
|
||||
<td><strong><?php echo wpdd_format_price($payout->amount, $payout->currency); ?></strong></td>
|
||||
<td><?php echo esc_html($payout->paypal_email); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$status_colors = array(
|
||||
'pending' => '#fef3c7; color: #92400e;',
|
||||
'completed' => '#d1fae5; color: #065f46;',
|
||||
'failed' => '#fee2e2; color: #991b1b;',
|
||||
'requested' => '#dbeafe; color: #1e40af;'
|
||||
);
|
||||
$status_color = isset($status_colors[$payout->status]) ? $status_colors[$payout->status] : '#f3f4f6; color: #374151;';
|
||||
?>
|
||||
<span style="padding: 2px 8px; border-radius: 3px; font-size: 12px; background: <?php echo $status_color; ?>">
|
||||
<?php echo esc_html(ucfirst($payout->status)); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo esc_html($payout->transaction_id ?: '-'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
echo $payout->processed_at
|
||||
? esc_html(date_i18n(get_option('date_format'), strtotime($payout->processed_at)))
|
||||
: '-';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div style="background: #fff; padding: 40px; border: 1px solid #ccd0d4; border-radius: 4px; text-align: center;">
|
||||
<h3><?php _e('No payout history', 'wp-digital-download'); ?></h3>
|
||||
<p><?php _e('Your payout requests will appear here once you make them.', 'wp-digital-download'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
private static function handle_payout_request() {
|
||||
global $wpdb;
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$balance = WPDD_Creator::get_creator_balance($user_id);
|
||||
$paypal_email = get_user_meta($user_id, 'wpdd_paypal_email', true);
|
||||
|
||||
if ($balance <= 0 || empty($paypal_email)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currency = get_option('wpdd_currency', 'USD');
|
||||
|
||||
// Create payout request
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'wpdd_payouts',
|
||||
array(
|
||||
'creator_id' => $user_id,
|
||||
'amount' => $balance,
|
||||
'currency' => $currency,
|
||||
'paypal_email' => $paypal_email,
|
||||
'status' => 'requested',
|
||||
'payout_method' => 'request',
|
||||
'created_at' => current_time('mysql')
|
||||
),
|
||||
array('%d', '%f', '%s', '%s', '%s', '%s', '%s')
|
||||
);
|
||||
|
||||
// Reset balance to 0 since it's now requested
|
||||
update_user_meta($user_id, 'wpdd_creator_balance', 0);
|
||||
|
||||
// Redirect to avoid resubmission
|
||||
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-creator-payouts&message=payout_requested'));
|
||||
exit;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user