Files
MokoDoliJoomShop/src/admin/src/Model/DashboardModel.php
T
Jonathan Miller a44e51ce5c feat(component): implement high-priority features (Issues #7-12)
- Category navigation: CategoryModel with hierarchical tree, category
  landing page with sidebar, breadcrumbs, and Joomla menu item types
- Stock display: StockHelper with In Stock/Low Stock/Out of Stock
  indicators, configurable threshold, and backorder support
- Tax calculation: TaxHelper with grouped tax breakdown, HT/TTC
  display modes, and configurable tax display setting
- Product search: SearchController with AJAX endpoint, text search
  via Dolibarr sqlfilters, price range, sorting, and category filter
- Order history: OrdersModel, Orders view with list and detail,
  PDF invoice download support, real-time Dolibarr status
- Admin dashboard: DashboardModel with product/order/customer counts,
  revenue metrics (daily/weekly/monthly), recent orders table

Also adds menu item type XML metadata for Products, Category, Cart,
Checkout, and My Orders views.

Resolves: #7, #8, #9, #10, #11, #12

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 17:56:09 -05:00

159 lines
3.7 KiB
PHP

<?php
/**
* @package MokoDoliJoomShop
* @subpackage com_mokodolijoomshop
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*/
namespace Moko\Component\MokoDoliJoomShop\Administrator\Model;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Moko\Component\MokoDoliJoomShop\Administrator\Helper\DolibarrClient;
/**
* Dashboard model — provides metrics and sync data for the admin dashboard.
*
* @since 1.0.0
*/
class DashboardModel extends BaseDatabaseModel
{
/**
* @var DolibarrClient
* @since 1.0.0
*/
private DolibarrClient $client;
/**
* Constructor.
*
* @param array $config Configuration array.
*
* @since 1.0.0
*/
public function __construct($config = [])
{
parent::__construct($config);
$this->client = new DolibarrClient();
}
/**
* Get product count from Dolibarr.
*
* @return int
*
* @since 1.0.0
*/
public function getProductCount(): int
{
$products = $this->client->get('/products', ['limit' => 0]);
return $products !== null ? \count($products) : 0;
}
/**
* Get local order count.
*
* @return int
*
* @since 1.0.0
*/
public function getOrderCount(): int
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('COUNT(*)')
->from($db->quoteName('#__mokodolijoomshop_orders'));
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* Get customer mapping count.
*
* @return int
*
* @since 1.0.0
*/
public function getCustomerCount(): int
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('COUNT(*)')
->from($db->quoteName('#__mokodolijoomshop_customers'));
$db->setQuery($query);
return (int) $db->loadResult();
}
/**
* Get recent orders from local table.
*
* @param int $limit Number of recent orders.
*
* @return array
*
* @since 1.0.0
*/
public function getRecentOrders(int $limit = 10): array
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('*')
->from($db->quoteName('#__mokodolijoomshop_orders'))
->order($db->quoteName('created') . ' DESC');
$db->setQuery($query, 0, $limit);
return $db->loadAssocList() ?: [];
}
/**
* Get revenue metrics.
*
* @return array{today: float, week: float, month: float}
*
* @since 1.0.0
*/
public function getRevenue(): array
{
$db = $this->getDatabase();
$now = Factory::getDate();
$today = $now->format('Y-m-d');
$week = Factory::getDate('-7 days')->format('Y-m-d');
$month = Factory::getDate('-30 days')->format('Y-m-d');
$revenue = ['today' => 0.0, 'week' => 0.0, 'month' => 0.0];
// Today
$query = $db->getQuery(true);
$query->select('COALESCE(SUM(' . $db->quoteName('total_ttc') . '), 0)')
->from($db->quoteName('#__mokodolijoomshop_orders'))
->where($db->quoteName('created') . ' >= ' . $db->quote($today . ' 00:00:00'));
$db->setQuery($query);
$revenue['today'] = (float) $db->loadResult();
// Week
$query = $db->getQuery(true);
$query->select('COALESCE(SUM(' . $db->quoteName('total_ttc') . '), 0)')
->from($db->quoteName('#__mokodolijoomshop_orders'))
->where($db->quoteName('created') . ' >= ' . $db->quote($week . ' 00:00:00'));
$db->setQuery($query);
$revenue['week'] = (float) $db->loadResult();
// Month
$query = $db->getQuery(true);
$query->select('COALESCE(SUM(' . $db->quoteName('total_ttc') . '), 0)')
->from($db->quoteName('#__mokodolijoomshop_orders'))
->where($db->quoteName('created') . ' >= ' . $db->quote($month . ' 00:00:00'));
$db->setQuery($query);
$revenue['month'] = (float) $db->loadResult();
return $revenue;
}
}