b05234ef1a
Layer 2 add-on for MokoSuite CRM. Field service operations for plumbing, electrical, HVAC, and general trades. Schema (12 tables): - Technicians (trade, certifications, GPS, service radius, vehicle) - Service Locations (customer properties with access notes, GPS) - Work Orders (full lifecycle: new > dispatched > en_route > on_site > in_progress > completed > invoiced, with priority/trade/category) - WO Line Items (labor, parts, materials, flat rate, permits) - WO Photos (before/during/after with GPS coordinates) - Service Agreements (recurring maintenance contracts with SLA) - Equipment (HVAC units, panels, water heaters with serial/warranty) - Vehicles (fleet tracking with mileage, inspection, GPS) - Truck Stock (per-vehicle parts inventory with reorder points) - Dispatch Log (assignment and routing history with GPS) - Estimates (on-site quoting with token-based customer acceptance) - Time Entries (per-WO labor tracking with overtime/travel flags) Helpers: - DispatchHelper: find best tech by trade/location/workload, dispatch board, auto-assignment, unassigned queue - WorkOrderHelper: create, status lifecycle, completion with signature, dashboard stats Infrastructure: - Joomla 6 (PHP 8.3+), admin dashboard with dispatch board - Git submodules: MokoSuite + MokoSuiteCRM - GPL-3.0 license
41 lines
1.7 KiB
PHP
41 lines
1.7 KiB
PHP
<?php
|
|
namespace Moko\Component\MokoSuiteField\Administrator\View\Dashboard;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
|
use Joomla\CMS\Toolbar\ToolbarHelper;
|
|
use Joomla\Database\DatabaseInterface;
|
|
|
|
class HtmlView extends BaseHtmlView
|
|
{
|
|
public object $stats;
|
|
public array $dispatchBoard = [];
|
|
public array $unassigned = [];
|
|
public array $urgent = [];
|
|
|
|
public function display($tpl = null): void
|
|
{
|
|
$this->stats = \Moko\Plugin\System\MokoSuiteField\Helper\WorkOrderHelper::getDashboardStats();
|
|
$this->dispatchBoard = \Moko\Plugin\System\MokoSuiteField\Helper\DispatchHelper::getDispatchBoard();
|
|
$this->unassigned = \Moko\Plugin\System\MokoSuiteField\Helper\DispatchHelper::getUnassigned();
|
|
|
|
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
|
|
|
// Urgent/emergency jobs
|
|
$db->setQuery($db->getQuery(true)
|
|
->select('wo.*, cd.name AS customer_name, loc.address')
|
|
->from($db->quoteName('#__mokosuitefield_work_orders', 'wo'))
|
|
->join('LEFT', $db->quoteName('#__contact_details', 'cd') . ' ON cd.id = wo.contact_id')
|
|
->join('LEFT', $db->quoteName('#__mokosuitefield_locations', 'loc') . ' ON loc.id = wo.location_id')
|
|
->where($db->quoteName('wo.priority') . ' IN (' . $db->quote('emergency') . ',' . $db->quote('urgent') . ')')
|
|
->where($db->quoteName('wo.status') . ' NOT IN (' . $db->quote('completed') . ',' . $db->quote('cancelled') . ',' . $db->quote('invoiced') . ')')
|
|
->order('FIELD(wo.priority,' . $db->quote('emergency') . ',' . $db->quote('urgent') . ') ASC, wo.created ASC'), 0, 10);
|
|
$this->urgent = $db->loadObjectList() ?: [];
|
|
|
|
ToolbarHelper::title('MokoSuite Field Service', 'icon-wrench');
|
|
parent::display($tpl);
|
|
}
|
|
}
|