getDatabase(); $db->setQuery($db->getQuery(true) ->select('t.id AS tech_id, cd.name AS tech_name, t.trade, t.status AS tech_status') ->select('(SELECT COUNT(*) FROM #__mokosuitefield_work_orders wo WHERE wo.technician_id = t.id AND wo.scheduled_date = CURDATE() AND wo.status NOT IN (' . $db->quote('completed') . ',' . $db->quote('cancelled') . ')) AS pending_jobs') ->select('(SELECT COUNT(*) FROM #__mokosuitefield_work_orders wo WHERE wo.technician_id = t.id AND wo.scheduled_date = CURDATE() AND wo.status = ' . $db->quote('completed') . ') AS completed_jobs') ->from($db->quoteName('#__mokosuitefield_technicians', 't')) ->join('LEFT', $db->quoteName('#__contact_details', 'cd') . ' ON cd.id = t.contact_id') ->where($db->quoteName('t.status') . ' != ' . $db->quote('inactive')) ->order('cd.name ASC')); return $db->loadObjectList() ?: []; } public function getGpsLog(int $techId, string $date = ''): array { $db = $this->getDatabase(); $date = $date ?: date('Y-m-d'); $db->setQuery($db->getQuery(true) ->select('*') ->from('#__mokosuitefield_dispatch_log') ->where('technician_id = ' . $techId) ->where('DATE(recorded_at) = ' . $db->quote($date)) ->order('recorded_at ASC')); return $db->loadObjectList() ?: []; } }