Initial Commit

This commit is contained in:
David Stone
2024-11-30 18:24:12 -07:00
commit e8f7955c1c
5432 changed files with 1397750 additions and 0 deletions

580
inc/functions/financial.php Normal file
View File

@ -0,0 +1,580 @@
<?php
/**
* Financial Functions
*
* @package WP_Ultimo\Functions
* @since 2.0.0
*/
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Database\Payments\Payment_Status;
use \WP_Ultimo\Database\Memberships\Membership_Status;
/**
* Calculates the Monthly Recurring Revenue of the network.
*
* @since 2.0.0
* @return float
*/
function wu_calculate_mrr() {
$total_mrr = 0;
$memberships = wu_get_memberships(array(
'recurring' => true,
'status__in' => array(
Membership_Status::ACTIVE,
),
));
foreach ($memberships as $membership) {
$recurring_amount = $membership->get_amount();
if (!$membership->is_recurring()) {
continue;
} // end if;
$duration = $membership->get_duration() ? $membership->get_duration() : 1;
$duration_unit = $membership->get_duration_unit();
$normalized_duration_unit = wu_convert_duration_unit_to_month($duration_unit);
$mrr = $recurring_amount / ($duration * $normalized_duration_unit);
$total_mrr += $mrr;
} // end foreach;
return $total_mrr;
} // end wu_calculate_mrr;
/**
* Converts the duration unit strings such as 'day', 'year' and such into
* a integer/float representing the amount of monhts.
*
* @since 2.0.0
*
* @param string $duration_unit The duration unit.
* @return float
*/
function wu_convert_duration_unit_to_month($duration_unit) {
$months = 1;
switch ($duration_unit) {
case 'day':
$months = 1 / 30;
break;
case 'week':
$months = 1 / 4;
break;
case 'month':
$months = 1;
break;
case 'year':
$months = 12;
break;
default:
$months = $months;
break;
} // end switch;
return $months;
} // end wu_convert_duration_unit_to_month;
/**
* Calculates the Annual Recurring Revenue.
*
* It is basically MRR * 12.
*
* @since 2.0.0
* @return float
*/
function wu_calculate_arr() {
return wu_calculate_mrr() * 12;
} // end wu_calculate_arr;
/**
* Calculates the total revenue.
*
* @since 2.0.0
*
* @param string $start_date The start date for the stat.
* @param string $end_date The end date for the stat.
* @param boolean $inclusive If true, will include payments on the start and end date.
* @return float
*/
function wu_calculate_revenue($start_date = false, $end_date = false, $inclusive = true) {
$total_revenue = 0;
$query_args = array(
'fields' => array('total'),
'date_query' => array(),
'status__in' => array(
Payment_Status::COMPLETED,
Payment_Status::PARTIAL,
),
);
if ($start_date) {
$query_args['date_query']['column'] = 'date_created';
$query_args['date_query']['after'] = $start_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
if ($end_date) {
$query_args['date_query']['column'] = 'date_created';
$query_args['date_query']['before'] = $end_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
$payments = wu_get_payments($query_args);
foreach ($payments as $payment) {
$total_revenue += (float) $payment->total;
} // end foreach;
return $total_revenue;
} // end wu_calculate_revenue;
/**
* Calculates the total refunds.
*
* @since 2.0.0
*
* @param string $start_date The start date for the stat.
* @param string $end_date The end date for the stat.
* @param boolean $inclusive If true, will include payments on the start and end date.
* @return float
*/
function wu_calculate_refunds($start_date = false, $end_date = false, $inclusive = true) {
$total_revenue = 0;
$query_args = array(
'fields' => array('refund_total'),
'date_query' => array(),
'status__in' => array(
Payment_Status::REFUND,
Payment_Status::PARTIAL_REFUND,
),
);
if ($start_date) {
$query_args['date_query']['column'] = 'date_created';
$query_args['date_query']['after'] = $start_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
if ($end_date) {
$query_args['date_query']['column'] = 'date_created';
$query_args['date_query']['before'] = $end_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
$payments = wu_get_payments($query_args);
foreach ($payments as $payment) {
$total_revenue += -(float) $payment->refund_total;
} // end foreach;
return $total_revenue;
} // end wu_calculate_refunds;
/**
* Calculates the taxes collected grouped by the rate.
*
* @since 2.0.0
*
* @param string $start_date The start date to compile data.
* @param string $end_date The end date to compile data.
* @param boolean $inclusive To include or not the start and end date.
* @return array
*/
function wu_calculate_taxes_by_rate($start_date = false, $end_date = false, $inclusive = true) {
$query_args = array(
'date_query' => array(),
);
if ($start_date) {
$query_args['date_query']['after'] = $start_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
if ($end_date) {
$query_args['date_query']['before'] = $end_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
$order = 0;
$taxes_paid_list = array();
$line_items_groups = \WP_Ultimo\Checkout\Line_Item::get_line_items($query_args);
foreach ($line_items_groups as $line_items_group) {
$order++;
foreach ($line_items_group as $line_item) {
$tax_name = $line_item->get_tax_label();
if ($line_item->get_tax_rate() <= 0) {
continue;
} // end if;
if (!wu_get_isset($taxes_paid_list, $tax_name)) {
$taxes_paid_list[$tax_name] = array(
'title' => $tax_name,
'country' => '',
'state' => '',
'order_count' => $order,
'tax_rate' => $line_item->get_tax_rate(),
'tax_total' => $line_item->get_tax_total(),
);
} else {
$taxes_paid_list[$tax_name]['tax_total'] += $line_item->get_tax_total();
$taxes_paid_list[$tax_name]['order_count'] += $order;
} // end if;
} // end foreach;
} // end foreach;
return $taxes_paid_list;
} // end wu_calculate_taxes_by_rate;
/**
* Aggregate financial data on a per product basis.
*
* @since 2.0.0
*
* @param string $start_date The start date to compile data.
* @param string $end_date The end date to compile data.
* @param boolean $inclusive To include or not the start and end date.
* @return array
*/
function wu_calculate_financial_data_by_product($start_date = false, $end_date = false, $inclusive = true) {
$query_args = array(
'date_query' => array(),
'payment_status' => Payment_Status::COMPLETED,
);
if ($start_date) {
$query_args['date_query']['after'] = $start_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
if ($end_date) {
$query_args['date_query']['before'] = $end_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
$line_items_groups = \WP_Ultimo\Checkout\Line_Item::get_line_items($query_args);
$data = array();
$products = wu_get_products();
foreach ($products as $product) {
$data[$product->get_id()] = array(
'label' => $product->get_name(),
'revenue' => 0,
);
} // end foreach;
foreach ($line_items_groups as $line_items_group) {
foreach ($line_items_group as $line_item) {
$product_id = $line_item->get_product_id();
if (empty($product_id)) {
continue;
} // end if;
if (!wu_get_isset($data, $product_id)) {
continue;
} // end if;
$data[$product_id]['revenue'] += $line_item->get_total();
} // end foreach;
} // end foreach;
uasort($data, fn($a, $b) => wu_sort_by_column($b, $a, 'revenue'));
return $data;
} // end wu_calculate_financial_data_by_product;
/**
* Calculates the taxes collected grouped by date.
*
* @since 2.0.0
*
* @param string $start_date The start date to compile data.
* @param string $end_date The end date to compile data.
* @param boolean $inclusive To include or not the start and end date.
* @return array
*/
function wu_calculate_taxes_by_day($start_date = false, $end_date = false, $inclusive = true) {
$query_args = array(
'date_query' => array(),
);
if ($start_date) {
$query_args['date_query']['after'] = $start_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
if ($end_date) {
$query_args['date_query']['before'] = $end_date;
$query_args['date_query']['inclusive'] = $inclusive;
} // end if;
$line_items_groups = \WP_Ultimo\Checkout\Line_Item::get_line_items($query_args);
$data = array();
$period = new \DatePeriod(
new \DateTime($start_date),
new \DateInterval('P1D'),
new \DateTime($end_date . ' 23:59:59')
);
$days = array_reverse(iterator_to_array($period));
foreach ($days as $day_datetime) {
$data[$day_datetime->format('Y-m-d')] = array(
'order_count' => 0,
'total' => 0,
'tax_total' => 0,
'net_profit' => 0,
);
} // end foreach;
foreach ($line_items_groups as $line_items_group) {
foreach ($line_items_group as $line_item) {
$date = gmdate('Y-m-d', strtotime((string) $line_item->date_created));
if (!wu_get_isset($data, $date)) {
$data[$date] = array(
'order_count' => 0,
'total' => $line_item->get_total(),
'tax_total' => $line_item->get_tax_total(),
'net_profit' => $line_item->get_total() - $line_item->get_tax_total(),
);
} else {
$data[$date]['order_count'] += 1;
$data[$date]['total'] += $line_item->get_total();
$data[$date]['tax_total'] += $line_item->get_tax_total();
$data[$date]['net_profit'] += $line_item->get_total() - $line_item->get_tax_total();
} // end if;
} // end foreach;
} // end foreach;
return $data;
} // end wu_calculate_taxes_by_day;
/**
* Calculates the taxes collected this year, segregated by month.
*
* @since 2.0.0
* @return array
*/
function wu_calculate_taxes_by_month() {
$cache = get_site_transient('wu_tax_monthly_stats');
if (is_array($cache)) {
return $cache;
} // end if;
$query_args = array(
'date_query' => array(
'after' => 'first day of January this year',
'before' => 'last day of December this year',
'inclusive' => true,
),
);
$line_items_groups = \WP_Ultimo\Checkout\Line_Item::get_line_items($query_args);
$data = array();
$period = new \DatePeriod(
new \DateTime($query_args['date_query']['after']),
new \DateInterval('P1M'),
new \DateTime($query_args['date_query']['before'])
);
$months = iterator_to_array($period);
foreach ($months as $month_datetime) {
$data[$month_datetime->format('n')] = array(
'order_count' => 0,
'total' => 0,
'tax_total' => 0,
'net_profit' => 0,
);
} // end foreach;
foreach ($line_items_groups as $line_items_group) {
foreach ($line_items_group as $line_item) {
$date = gmdate('n', strtotime((string) $line_item->date_created));
if (!wu_get_isset($data, $date)) {
$data[$date] = array(
'order_count' => 0,
'total' => $line_item->get_total(),
'tax_total' => $line_item->get_tax_total(),
'net_profit' => $line_item->get_total() - $line_item->get_tax_total(),
);
} else {
$data[$date]['order_count'] += 1;
$data[$date]['total'] += $line_item->get_total();
$data[$date]['tax_total'] += $line_item->get_tax_total();
$data[$date]['net_profit'] += $line_item->get_total() - $line_item->get_tax_total();
} // end if;
} // end foreach;
} // end foreach;
set_site_transient('wu_tax_monthly_stats', $data);
return $data;
} // end wu_calculate_taxes_by_month;
/**
* Returns the number of sign-ups by form slug.
*
* @since 2.0.0
*
* @param string $start_date The start date to compile data.
* @param string $end_date The end date to compile data.
* @param boolean $inclusive To include or not the start and end date.
* @return array
*/
function wu_calculate_signups_by_form($start_date = false, $end_date = false, $inclusive = true) {
global $wpdb;
$query = array(
'date_query' => array(),
);
if ($start_date) {
$query['date_query']['after'] = $start_date;
$query['date_query']['inclusive'] = $inclusive;
} // end if;
if ($end_date) {
$query['date_query']['before'] = $end_date;
$query['date_query']['inclusive'] = $inclusive;
} // end if;
$date_query = new \WP_Date_Query($query['date_query']);
$date_query_sql = $date_query->get_sql();
$date_query_sql = str_replace($wpdb->base_prefix . 'posts.post_date', 'date_registered', $date_query_sql);
// phpcs:disable;
$query_sql = "
SELECT signup_form, COUNT(id) as count
FROM {$wpdb->base_prefix}wu_customers as d
WHERE 1 = 1
AND signup_form IS NOT NULL
{$date_query_sql}
GROUP BY signup_form
ORDER BY count DESC
";
$results = $wpdb->get_results($query_sql); // phpcs:ignore
return $results;
} // end wu_calculate_signups_by_form;