'wpdd_creator'));
// If creator is selected, show their transactions
if ($creator_id) {
self::render_transactions($creator_id, $date_from, $date_to, $type_filter, true);
} else {
?>
' . __('Creator not found.', 'wp-digital-download') . '
';
return;
}
// Fetch all transactions for this creator
$transactions = array();
// Get earnings (sales)
if ($type_filter === 'all' || $type_filter === 'earnings') {
$earnings = $wpdb->get_results($wpdb->prepare(
"SELECT e.*, o.order_number, o.customer_name, o.customer_email, p.post_title as product_name
FROM {$wpdb->prefix}wpdd_creator_earnings e
LEFT JOIN {$wpdb->prefix}wpdd_orders o ON e.order_id = o.id
LEFT JOIN {$wpdb->posts} p ON e.product_id = p.ID
WHERE e.creator_id = %d
AND DATE(e.created_at) BETWEEN %s AND %s
ORDER BY e.created_at DESC",
$creator_id, $date_from, $date_to
));
foreach ($earnings as $earning) {
$transactions[] = array(
'date' => $earning->created_at,
'type' => 'earning',
'description' => sprintf(__('Sale: %s to %s', 'wp-digital-download'),
$earning->product_name, $earning->customer_name),
'order_number' => $earning->order_number,
'gross_amount' => $earning->sale_amount,
'commission' => $earning->sale_amount - $earning->creator_earning,
'net_amount' => $earning->creator_earning,
'balance_change' => '+' . $earning->creator_earning,
'status' => $earning->payout_status,
'payout_id' => $earning->payout_id
);
}
}
// Get payouts
if ($type_filter === 'all' || $type_filter === 'payouts') {
$payouts = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}wpdd_payouts
WHERE creator_id = %d
AND DATE(created_at) BETWEEN %s AND %s
ORDER BY created_at DESC",
$creator_id, $date_from, $date_to
));
foreach ($payouts as $payout) {
$transactions[] = array(
'date' => $payout->created_at,
'type' => 'payout',
'description' => sprintf(__('Payout to %s', 'wp-digital-download'), $payout->paypal_email),
'order_number' => $payout->transaction_id ?: 'N/A',
'gross_amount' => 0,
'commission' => 0,
'net_amount' => -$payout->amount,
'balance_change' => '-' . $payout->amount,
'status' => $payout->status,
'payout_id' => $payout->id
);
}
}
// Get adjustments
if ($type_filter === 'all' || $type_filter === 'adjustments') {
$adjustments = $wpdb->get_results($wpdb->prepare(
"SELECT a.*, u.display_name as adjusted_by_name
FROM {$wpdb->prefix}wpdd_balance_adjustments a
LEFT JOIN {$wpdb->users} u ON a.adjusted_by = u.ID
WHERE a.creator_id = %d
AND DATE(a.created_at) BETWEEN %s AND %s
ORDER BY a.created_at DESC",
$creator_id, $date_from, $date_to
));
foreach ($adjustments as $adjustment) {
$amount_change = $adjustment->adjustment_type === 'add' ? $adjustment->amount : -$adjustment->amount;
$transactions[] = array(
'date' => $adjustment->created_at,
'type' => 'adjustment',
'description' => sprintf(__('Manual adjustment: %s (by %s)', 'wp-digital-download'),
$adjustment->reason, $adjustment->adjusted_by_name),
'order_number' => 'ADJ-' . $adjustment->id,
'gross_amount' => 0,
'commission' => 0,
'net_amount' => $amount_change,
'balance_change' => ($amount_change >= 0 ? '+' : '') . $amount_change,
'status' => 'completed',
'payout_id' => null
);
}
}
// Sort transactions by date
usort($transactions, function($a, $b) {
return strtotime($b['date']) - strtotime($a['date']);
});
// Calculate running balance
$current_balance = WPDD_Creator::get_creator_balance($creator_id);
$running_balance = $current_balance;
// Calculate balance by going backwards from current
for ($i = 0; $i < count($transactions); $i++) {
$transactions[$i]['running_balance'] = $running_balance;
if ($i < count($transactions) - 1) {
$running_balance -= floatval(str_replace('+', '', $transactions[$i]['balance_change']));
}
}
?>
display_name);
} else {
_e('My Transaction History', 'wp-digital-download');
}
?>
()
|
|
|
|
|
|
|
|
|
|
' . __('Sale', 'wp-digital-download');
break;
case 'payout':
$type_badge = ' ' . __('Payout', 'wp-digital-download');
break;
case 'adjustment':
$type_badge = ' ' . __('Adjustment', 'wp-digital-download');
break;
}
echo $type_badge;
?>
|
|
|
0 ? wpdd_format_price($transaction['gross_amount']) : '-'; ?> |
0 ? wpdd_format_price($transaction['commission']) : '-'; ?> |
= 0 ? '+' : '') . wpdd_format_price(abs($transaction['net_amount'])); ?>
|
|
|
get_results($wpdb->prepare(
"SELECT e.*, o.order_number, o.customer_name, o.customer_email, p.post_title as product_name
FROM {$wpdb->prefix}wpdd_creator_earnings e
LEFT JOIN {$wpdb->prefix}wpdd_orders o ON e.order_id = o.id
LEFT JOIN {$wpdb->posts} p ON e.product_id = p.ID
WHERE e.creator_id = %d
AND DATE(e.created_at) BETWEEN %s AND %s
ORDER BY e.created_at DESC",
$creator_id, $date_from, $date_to
));
foreach ($earnings as $earning) {
$transactions[] = array(
'date' => $earning->created_at,
'type' => 'earning',
'description' => sprintf(__('Sale: %s to %s', 'wp-digital-download'),
$earning->product_name, $earning->customer_name),
'order_number' => $earning->order_number,
'gross_amount' => $earning->sale_amount,
'commission' => $earning->sale_amount - $earning->creator_earning,
'net_amount' => $earning->creator_earning,
'balance_change' => '+' . $earning->creator_earning,
'status' => $earning->payout_status,
'payout_id' => $earning->payout_id
);
}
}
// Get payouts
if ($type_filter === 'all' || $type_filter === 'payouts') {
$payouts = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}wpdd_payouts
WHERE creator_id = %d
AND DATE(created_at) BETWEEN %s AND %s
ORDER BY created_at DESC",
$creator_id, $date_from, $date_to
));
foreach ($payouts as $payout) {
$transactions[] = array(
'date' => $payout->created_at,
'type' => 'payout',
'description' => sprintf(__('Payout to %s', 'wp-digital-download'), $payout->paypal_email),
'order_number' => $payout->transaction_id ?: 'N/A',
'gross_amount' => 0,
'commission' => 0,
'net_amount' => -$payout->amount,
'balance_change' => '-' . $payout->amount,
'status' => $payout->status,
'payout_id' => $payout->id
);
}
}
// Get adjustments
if ($type_filter === 'all' || $type_filter === 'adjustments') {
$adjustments = $wpdb->get_results($wpdb->prepare(
"SELECT a.*, u.display_name as adjusted_by_name
FROM {$wpdb->prefix}wpdd_balance_adjustments a
LEFT JOIN {$wpdb->users} u ON a.adjusted_by = u.ID
WHERE a.creator_id = %d
AND DATE(a.created_at) BETWEEN %s AND %s
ORDER BY a.created_at DESC",
$creator_id, $date_from, $date_to
));
foreach ($adjustments as $adjustment) {
$amount_change = $adjustment->adjustment_type === 'add' ? $adjustment->amount : -$adjustment->amount;
$transactions[] = array(
'date' => $adjustment->created_at,
'type' => 'adjustment',
'description' => sprintf(__('Manual adjustment: %s (by %s)', 'wp-digital-download'),
$adjustment->reason, $adjustment->adjusted_by_name),
'order_number' => 'ADJ-' . $adjustment->id,
'gross_amount' => 0,
'commission' => 0,
'net_amount' => $amount_change,
'balance_change' => ($amount_change >= 0 ? '+' : '') . $amount_change,
'status' => 'completed',
'payout_id' => null
);
}
}
// Sort transactions by date
usort($transactions, function($a, $b) {
return strtotime($b['date']) - strtotime($a['date']);
});
// Calculate running balance
$current_balance = WPDD_Creator::get_creator_balance($creator_id);
$running_balance = $current_balance;
// Calculate balance by going backwards from current
for ($i = 0; $i < count($transactions); $i++) {
$transactions[$i]['running_balance'] = $running_balance;
if ($i < count($transactions) - 1) {
$running_balance -= floatval(str_replace('+', '', $transactions[$i]['balance_change']));
}
}
return $transactions;
}
private static function handle_export_request($creator_id, $transactions, $date_from, $date_to, $format) {
$creator = get_userdata($creator_id);
if ($format === 'csv') {
self::export_csv($transactions, $creator, $date_from, $date_to);
} elseif ($format === 'pdf') {
self::export_pdf($transactions, $creator, $date_from, $date_to);
}
}
private static function export_csv($transactions, $creator, $date_from, $date_to) {
$filename = sprintf('transactions_%s_%s_to_%s.csv',
sanitize_title($creator->display_name),
$date_from,
$date_to
);
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=' . $filename);
$output = fopen('php://output', 'w');
// Add BOM for Excel UTF-8 compatibility
fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
// Header row
fputcsv($output, array(
'Date',
'Type',
'Description',
'Order/Reference',
'Gross Amount',
'Commission',
'Net Amount',
'Running Balance',
'Status'
));
// Data rows
foreach ($transactions as $transaction) {
fputcsv($output, array(
date('Y-m-d H:i:s', strtotime($transaction['date'])),
ucfirst($transaction['type']),
$transaction['description'],
$transaction['order_number'],
$transaction['gross_amount'] > 0 ? number_format($transaction['gross_amount'], 2) : '',
$transaction['commission'] > 0 ? number_format($transaction['commission'], 2) : '',
number_format(abs($transaction['net_amount']), 2) . ($transaction['net_amount'] < 0 ? ' (Debit)' : ''),
number_format($transaction['running_balance'], 2),
ucfirst($transaction['status'])
));
}
fclose($output);
exit;
}
private static function export_pdf($transactions, $creator, $date_from, $date_to) {
// Create a clean PDF-ready HTML document
$filename = sprintf('transactions_%s_%s_to_%s.pdf',
sanitize_title($creator->display_name),
$date_from,
$date_to
);
// Set headers for PDF display/download
header('Content-Type: text/html; charset=utf-8');
header('Content-Disposition: inline; filename=' . $filename);
header('X-Robots-Tag: noindex, nofollow');
?>
display_name); ?>
display_name); ?>
|
|
|
|
|
|
|
|
|
|
|
= 0 ? '+' : '') . wpdd_format_price(abs($transaction['net_amount'])); ?>
|
|
|