efae025a2f
- Add CSRF token validation on EstimateView approve/reject forms - Add status guard on reject branch (prevent reversing approved estimates) - Fix loc.* column collision in WorkOrdersModel::getWorkOrder (overwrote wo.id) - Add (int) cast on all query parameter concatenations - Wrap InvoiceHelper::generateFromWorkOrder in database transaction - Replace magic 0.5 divisor with AVG_SPEED_MPH constant in RouteHelper
63 lines
2.9 KiB
PHP
63 lines
2.9 KiB
PHP
<?php
|
|
namespace Moko\Component\MokoSuiteField\Administrator\Model;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
|
|
|
class WorkOrdersModel extends BaseDatabaseModel
|
|
{
|
|
public function getItems(string $status = '', string $trade = '', int $techId = 0, string $search = '', string $date = '', int $limit = 50, int $offset = 0): array
|
|
{
|
|
$db = $this->getDatabase();
|
|
$query = $db->getQuery(true)
|
|
->select('wo.*, cd.name AS customer_name, loc.address, loc.city, loc.state, loc.zip')
|
|
->select('t_cd.name AS tech_name')
|
|
->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')
|
|
->join('LEFT', $db->quoteName('#__mokosuitefield_technicians', 't') . ' ON t.id = wo.technician_id')
|
|
->join('LEFT', $db->quoteName('#__contact_details', 't_cd') . ' ON t_cd.id = t.contact_id')
|
|
->order('wo.scheduled_date DESC, wo.priority DESC');
|
|
|
|
if ($status) $query->where($db->quoteName('wo.status') . ' = ' . $db->quote($status));
|
|
if ($trade) $query->where($db->quoteName('wo.trade') . ' = ' . $db->quote($trade));
|
|
if ($techId) $query->where('wo.technician_id = ' . $techId);
|
|
if ($date) $query->where('wo.scheduled_date = ' . $db->quote($date));
|
|
if ($search) {
|
|
$query->where('(' . $db->quoteName('wo.wo_number') . ' LIKE ' . $db->quote('%' . $search . '%')
|
|
. ' OR ' . $db->quoteName('wo.description') . ' LIKE ' . $db->quote('%' . $search . '%')
|
|
. ' OR ' . $db->quoteName('cd.name') . ' LIKE ' . $db->quote('%' . $search . '%') . ')');
|
|
}
|
|
|
|
$db->setQuery($query, $offset, $limit);
|
|
return $db->loadObjectList() ?: [];
|
|
}
|
|
|
|
public function getWorkOrder(int $id): ?object
|
|
{
|
|
$db = $this->getDatabase();
|
|
$db->setQuery($db->getQuery(true)
|
|
->select('wo.*, cd.name AS customer_name, t_cd.name AS tech_name')
|
|
->select('loc.address, loc.city, loc.state, loc.zip, loc.latitude, loc.longitude, loc.name AS location_name')
|
|
->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')
|
|
->join('LEFT', $db->quoteName('#__mokosuitefield_technicians', 't') . ' ON t.id = wo.technician_id')
|
|
->join('LEFT', $db->quoteName('#__contact_details', 't_cd') . ' ON t_cd.id = t.contact_id')
|
|
->where('wo.id = ' . (int) $id));
|
|
return $db->loadObject();
|
|
}
|
|
|
|
public function getStatusCounts(): object
|
|
{
|
|
$db = $this->getDatabase();
|
|
$db->setQuery($db->getQuery(true)
|
|
->select('status, COUNT(*) AS cnt')
|
|
->from('#__mokosuitefield_work_orders')
|
|
->group('status'));
|
|
$rows = $db->loadObjectList('status') ?: [];
|
|
return (object) array_map(fn($r) => (int) $r->cnt, (array) $rows);
|
|
}
|
|
}
|