| Current Path : /var/www/html/administrator/components/com_osmembership/model/ |
| Current File : /var/www/html/administrator/components/com_osmembership/model/dashboard.php |
<?php
/**
* @package Joomla
* @subpackage Membership Pro
* @author Tuan Pham Ngoc
* @copyright Copyright (C) 2012 - 2026 Ossolution Team
* @license GNU/GPL, see LICENSE.php
*/
defined('_JEXEC') or die;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Updater\Updater;
use Joomla\Component\Installer\Administrator\Model\UpdateModel;
use Joomla\Database\DatabaseDriver;
class OSMembershipModelDashboard extends MPFModel
{
/**
* Constructor
*
* @throws Exception
*/
public function __construct()
{
parent::__construct();
$this->state->insert('filter_plan_id', 'int', 0)
->insert('filter_subscription_type', 'string', '')
->insert('filter_duration', 'string', '');
}
/**
* Get latest subscriptions
*
* @return array
*/
public function getLatestSubscriptions()
{
return MPFModel::getTempInstance('Subscriptions', 'OSMembershipModel')
->limitstart(0)
->limit(6)
->filter_order('tbl.created_date')
->filter_order_Dir('DESC')
->plan_id($this->state->get('filter_plan_id', 0))
->getData();
}
/***
* Get total revenue
*
* @return float
*/
public function getTotalRevenue()
{
[$fromDate, $toDate] = $this->getFromDateAndToDateFromSelectedDuration();
return $this->getRevenueForDuration(
$fromDate,
$toDate,
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
}
/***
* Get total revenue
*
* @return float
*/
public function getTotalSubscriptions()
{
[$fromDate, $toDate] = $this->getFromDateAndToDateFromSelectedDuration();
return $this->getTotalSubscriptionsForDuration(
$fromDate,
$toDate,
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
}
/**
* Get total active subscriptions
*
* @return int
* @throws Exception
*/
public function getTotalActiveSubscriptions()
{
[$fromDate, $toDate] = $this->getFromDateAndToDateFromSelectedDuration();
return $this->getTotalActiveSubscriptionsForDuration(
$fromDate,
$toDate,
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
}
/**
* Get total refund amount
*
* @return int
* @throws Exception
*/
public function getTotalRefundAmount()
{
[$fromDate, $toDate] = $this->getFromDateAndToDateFromSelectedDuration();
return $this->getTotalRefundAmountForDuration(
$fromDate,
$toDate,
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
}
/**
* Method to get last 12 months sales data
*
* @param int $planId
*
* @return array
*/
public function getMonthlyRevenueChartData()
{
$today = Factory::getDate('Now', Factory::getApplication()->get('offset'));
$today->setDate($today->format('Y', true), $today->format('n', true), 1);
$data = [
'labels' => [],
'total_revenue_dataset' => [],
'refund_amount_dataset' => [],
];
for ($i = 0; $i < 13; $i++)
{
if ($i > 0)
{
$today->modify('-1 month');
}
$month = $today->format('n', true);
$year = $today->format('Y', true);
$startMonth = clone $today;
$endMonth = clone $today;
$startMonth->setTime(0, 0, 0);
$startMonth->setDate($year, $month, 1);
$endMonth->setTime(23, 59, 59);
$endMonth->setDate($year, $month, $today->format('t', true));
$data['total_revenue_dataset'][] = $this->getRevenueForDuration(
$startMonth->toSql(),
$endMonth->toSql(),
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
$data['refund_amount_dataset'][] = $this->getTotalRefundAmountForDuration(
$startMonth->toSql(),
$endMonth->toSql(),
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
$data['labels'][] = $today->format('M') . '/ ' . $year;
}
$data['labels'] = array_reverse($data['labels']);
$data['total_revenue_dataset'] = array_reverse($data['total_revenue_dataset']);
$data['refund_amount_dataset'] = array_reverse($data['refund_amount_dataset']);
return $data;
}
/**
* Get sales statistic for each date in a given duration
*
* @return array
*/
public function getDailyRevenueChartData()
{
$fromDate = Factory::getDate('now', Factory::getApplication()->get('offset'))
->modify('-1 month');
$toDate = Factory::getDate('now', Factory::getApplication()->get('offset'));
// Set from date to the beginning of day
$fromDate->setTime(0, 0, 0);
// Set to date to the end of days
$toDate->setTime(23, 59, 59);
$data = [
'labels' => [],
'total_revenue_dataset' => [],
'refund_amount_dataset' => [],
];
$i = 0;
while ($fromDate < $toDate)
{
$startDay = clone $fromDate;
$startDay->setTime(0, 0, 0);
$endDay = clone $fromDate;
$endDay->setTime(23, 59, 59);
$data['total_revenue_dataset'][] = $this->getRevenueForDuration(
$startDay->toSql(),
$endDay->toSql(),
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
$data['refund_amount_dataset'][] = $this->getTotalRefundAmountForDuration(
$startDay->toSql(),
$endDay->toSql(),
$this->state->filter_plan_id,
$this->state->filter_subscription_type
);
if ($i % 3 === 0)
{
$data['labels'][] = $fromDate->format('d-M-y', true);
}
else
{
$data['labels'][] = '';
}
$i++;
$fromDate->modify('+1 day');
}
return $data;
}
/**
* Method to get revenue by payment method chart data
*
* @return array
*/
public function getRevenueByPaymentMethodsChartData(): array
{
[$fromDate, $toDate] = $this->getFromDateAndToDateFromSelectedDuration();
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from('#__osmembership_plugins')
->where('published = 1');
$db->setQuery($query);
if (!$db->loadResult())
{
return [];
}
$query->clear()
->select('name, title')
->from('#__osmembership_plugins');
$db->setQuery($query);
$paymentMethods = $db->loadObjectList('name');
$query->clear()
->select('payment_method, IFNULL(SUM(gross_amount), 0) AS payment_method_revenue')
->from('#__osmembership_subscribers')
->where('published IN (1,2)')
->where('CHAR_LENGTH(payment_method) > 0')
->where('group_admin_id = 0')
->group('payment_method');
if ($fromDate)
{
$query->where('created_date >= ' . $db->quote($fromDate));
}
if ($toDate)
{
$query->where('created_date <=' . $db->quote($toDate));
}
if ($this->state->filter_subscription_type)
{
$query->where('act = ' . $db->quote($this->state->filter_subscription_type));
}
if ($this->state->filter_plan_id)
{
$query->where('plan_id = ' . (int) $this->state->filter_plan_id);
}
$db->setQuery($query);
$rows = $db->loadObjectList();
$totalRevenue = 0;
foreach ($rows as $row)
{
$totalRevenue += $row->payment_method_revenue;
$row->payment_method_title = isset($paymentMethods[$row->payment_method]) ? $paymentMethods[$row->payment_method]->title : $row->payment_method;
}
$data = [];
$config = OSMembershipHelper::getConfig();
if ($totalRevenue > 0)
{
$totalPercent = 0;
$label = '';
foreach ($rows as $row)
{
$percent = round($row->payment_method_revenue / $totalRevenue * 100, 2);
$totalPercent += $percent;
$label = $row->payment_method_title
. ' - ' . OSMembershipHelper::formatCurrency($row->payment_method_revenue, $config);
$data[$label] = $percent;
}
// Make sure total percent is 100%
if ($totalPercent < 100)
{
$data[$label] = round(
($data[$label] + 100 - $totalPercent) / 100,
2
);
}
}
return $data;
}
/**
* Get total subscriptions for given duration
*
* @param string $fromDate
* @param string $toDate
* @param int $planId
* @param string $subscriptionType
*
* @return int
*/
protected function getTotalSubscriptionsForDuration(
$fromDate = null,
$toDate = null,
$planId = null,
$subscriptionType = null
) {
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from('#__osmembership_subscribers')
->where('(published IN (1,2) OR (published = 0 AND payment_method LIKE "os_offline%"))')
->where('group_admin_id = 0');
if ($fromDate)
{
$query->where('created_date >= ' . $db->quote($fromDate));
}
if ($toDate)
{
$query->where('created_date <=' . $db->quote($toDate));
}
if ($planId)
{
$query->where('plan_id = ' . (int) $planId);
}
if ($subscriptionType)
{
$query->where('act = ' . $db->quote($subscriptionType));
}
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* Get total active subscriptions for given duration
*
* @param string $fromDate
* @param string $toDate
* @param int $planId
*
* @return int
*/
protected function getTotalActiveSubscriptionsForDuration(
$fromDate = null,
$toDate = null,
$planId = null,
$subscriptionType = null
) {
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from('#__osmembership_subscribers')
->where('published = 1')
->where('group_admin_id = 0');
if ($fromDate)
{
$query->where('created_date >= ' . $db->quote($fromDate));
}
if ($toDate)
{
$query->where('created_date <=' . $db->quote($toDate));
}
if ($planId)
{
$query->where('plan_id = ' . (int) $planId);
}
if ($subscriptionType)
{
$query->where('act = ' . $db->quote($subscriptionType));
}
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* Get total refund amount for given duration
*
* @param string $fromDate
* @param string $toDate
* @param int $planId
* @param string $subscriptionType
*
* @return int
*/
protected function getTotalRefundAmountForDuration(
$fromDate = null,
$toDate = null,
$planId = null,
$subscriptionType = null
) {
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('IFNULL(SUM(gross_amount), 0)')
->from('#__osmembership_subscribers')
->where('published = 4')
->where('group_admin_id = 0');
if ($fromDate)
{
$query->where('created_date >= ' . $db->quote($fromDate));
}
if ($toDate)
{
$query->where('created_date <=' . $db->quote($toDate));
}
if ($planId)
{
$query->where('plan_id = ' . (int) $planId);
}
if ($subscriptionType)
{
$query->where('act = ' . $db->quote($subscriptionType));
}
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* @param string $fromDate
* @param string $toDate
* @param int $planId
* @param string $subscriptionType
*
* @return float
*/
protected function getRevenueForDuration($fromDate = null, $toDate = null, $planId = null, $subscriptionType = null)
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('IFNULL(SUM(gross_amount), 0)')
->from('#__osmembership_subscribers')
->where('published IN (1,2)')
->where('group_admin_id = 0');
if ($fromDate)
{
$query->where('created_date >= ' . $db->quote($fromDate));
}
if ($toDate)
{
$query->where('created_date <=' . $db->quote($toDate));
}
if ($subscriptionType)
{
$query->where('act = ' . $db->quote($subscriptionType));
}
if ($planId)
{
$query->where('plan_id = ' . (int) $planId);
}
$db->setQuery($query);
return (float) $db->loadResult();
}
/**
* Method to get from date and to date from selected duration
*
* @return array|null[]
*
* @throws Exception
*/
protected function getFromDateAndToDateFromSelectedDuration()
{
if ($this->state->filter_duration)
{
return OSMembershipHelper::getDateDuration($this->state->filter_duration);
}
return [null, null];
}
/**
* Check update result
*
* @return array
*/
public function checkUpdate()
{
// Get the caching duration.
$component = ComponentHelper::getComponent('com_installer');
$params = $component->params;
$cache_timeout = $params->get('cachetimeout', 6);
$cache_timeout = 3600 * $cache_timeout;
// Get the minimum stability.
$minimum_stability = $params->get('minimum_stability', Updater::STABILITY_STABLE);
/* @var UpdateModel $model */
$model = Factory::getApplication()->bootComponent('com_installer')->getMVCFactory()
->createModel('Update', 'Administrator', ['ignore_request' => true]);
$model->purge();
/* @var DatabaseDriver $db */
$db = Factory::getContainer()->get('db');
$query = $db->getQuery(true)
->select('extension_id')
->from('#__extensions')
->where('`type` = "package"')
->where('`element` = "pkg_osmembership"');
$db->setQuery($query);
$eid = (int) $db->loadResult();
$result['status'] = 0;
if ($eid)
{
$ret = Updater::getInstance()->findUpdates($eid, $cache_timeout, $minimum_stability);
if ($ret)
{
$model->setState('list.start', 0);
$model->setState('list.limit', 0);
$model->setState('filter.extension_id', $eid);
$updates = $model->getItems();
$result['status'] = 2;
$result['version'] = '';
if (count($updates))
{
$result['message'] = Text::sprintf('OSM_UPDATE_CHECKING_UPDATEFOUND', $updates[0]->version);
$result['version'] = $updates[0]->version;
}
else
{
$result['message'] = Text::sprintf('OSM_UPDATE_CHECKING_UPDATEFOUND', null);
}
}
else
{
$result['status'] = 1;
$result['message'] = Text::_('OSM_UPDATE_CHECKING_UPTODATE');
}
}
return $result;
}
}