From 8935b4eb2bb1af7174f1de420a8ec9f52217bd24 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 27 Jun 2026 15:23:25 -0500 Subject: [PATCH] feat: initial scaffold --- .gitignore | 7 + CHANGELOG.md | 15 +- CLAUDE.md | 5 +- README.md | 91 ++++- .../com_mokosuitelogistics/admin/access.xml | 25 +- .../com_mokosuitelogistics/admin/config.xml | 40 ++- .../language/en-GB/com_mokosuitelogistics.ini | 19 +- .../en-GB/com_mokosuitelogistics.sys.ini | 6 +- .../admin/services/provider.php | 32 +- .../src/Controller/DisplayController.php | 10 +- .../admin/src/Model/DeliveriesModel.php | 35 ++ .../admin/src/Model/DriversModel.php | 35 ++ .../src/Model/LogisticsDashboardModel.php | 13 +- .../admin/src/Model/OrdersModel.php | 52 +++ .../admin/src/Model/PricingRulesModel.php | 35 ++ .../admin/src/Model/ProofsModel.php | 35 ++ .../admin/src/Model/RoutesModel.php | 35 ++ .../admin/src/Model/WarehousesModel.php | 35 ++ .../admin/src/View/Deliveries/HtmlView.php | 32 ++ .../admin/src/View/Drivers/HtmlView.php | 32 ++ .../src/View/LogisticsDashboard/HtmlView.php | 24 +- .../admin/src/View/Orders/HtmlView.php | 32 ++ .../admin/src/View/PricingRules/HtmlView.php | 32 ++ .../admin/src/View/Proofs/HtmlView.php | 32 ++ .../admin/src/View/Routes/HtmlView.php | 32 ++ .../admin/src/View/Warehouses/HtmlView.php | 32 ++ .../admin/tmpl/deliveries/default.php | 14 + .../admin/tmpl/drivers/default.php | 14 + .../admin/tmpl/logisticsdashboard/default.php | 59 +++- .../admin/tmpl/orders/default.php | 68 ++++ .../admin/tmpl/pricingrules/default.php | 14 + .../admin/tmpl/proofs/default.php | 14 + .../admin/tmpl/routes/default.php | 14 + .../admin/tmpl/warehouses/default.php | 14 + .../mokosuitelogistics.xml | 64 ++-- .../en-GB/plg_system_mokosuitelogistics.ini | 5 +- .../plg_system_mokosuitelogistics.sys.ini | 5 +- .../mokosuitelogistics.xml | 105 +++--- .../services/provider.php | 32 +- .../sql/install.mysql.sql | 313 +++++++++--------- .../sql/uninstall.mysql.sql | 12 +- .../src/Extension/Logistics.php | 20 +- .../src/Helper/LogisticsHelper.php | 87 +++++ .../mokosuitelogistics.xml | 28 +- .../services/provider.php | 29 +- .../src/Extension/MokoSuiteLogistics.php | 44 +-- source/pkg_mokosuitelogistics.xml | 25 +- 47 files changed, 1349 insertions(+), 404 deletions(-) create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/DeliveriesModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/DriversModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/OrdersModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/PricingRulesModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/ProofsModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/RoutesModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/Model/WarehousesModel.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/Deliveries/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/Drivers/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/Orders/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/PricingRules/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/Proofs/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/Routes/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/src/View/Warehouses/HtmlView.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/deliveries/default.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/drivers/default.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/orders/default.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/pricingrules/default.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/proofs/default.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/routes/default.php create mode 100644 source/packages/com_mokosuitelogistics/admin/tmpl/warehouses/default.php create mode 100644 source/packages/plg_system_mokosuitelogistics/src/Helper/LogisticsHelper.php diff --git a/.gitignore b/.gitignore index b919835..0388e51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,12 @@ +# MokoSuite standard ignores .claude/ .mcp.json TODO.md +vendor/ +node_modules/ +.env *.min.css *.min.js +.DS_Store +Thumbs.db +*.ppk diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0448f..e98e0e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,11 @@ ### Added - **Repository** -- initial repo creation with scaffolding -- **System Plugin** -- Extension class, service provider -- **SQL Schema** -- 8 tables -- **Admin Component** -- 6 views: Dashboard, Shipments, Routes, Carriers, Warehouses, Packages -- **Webservices Plugin** -- 6 API routes -- **Configuration** -- basic settings fieldset -- **Access Control** -- core permissions -- **Language Files** -- en-GB translations +- **System Plugin** -- Extension class, service provider, LogisticsHelper +- **SQL Schema** -- 8 tables: orders, deliveries, routes, route_stops, delivery_proofs, pricing_rules, drivers, warehouses +- **Admin Component** -- 8 views with ListModels: dashboard, orders, deliveries, routes, warehouses, pricing rules, drivers, proofs +- **Admin Templates** -- functional Joomla 6 list views with pagination and status badges +- **Webservices Plugin** -- 7 API routes: orders, deliveries, routes, warehouses, pricing rules, drivers, proofs +- **Configuration** -- 11 settings across basic, delivery, pricing, notifications +- **Access Control** -- 15 permissions for granular role-based access +- **Component Language Files** -- en-GB translations for menu, submenu, and extension manager diff --git a/CLAUDE.md b/CLAUDE.md index eaf695b..4a17dec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ # MokoSuiteLogistics -Layer 2 — Fleet logistics, shipment tracking, route planning, warehouse management +Delivery management, route optimization, courier dispatch, and proof of delivery for Joomla 6. ## Quick Reference @@ -10,10 +10,11 @@ Layer 2 — Fleet logistics, shipment tracking, route planning, warehouse m | **Layer** | 2 (requires: Client, CRM) | | **Language** | PHP 8.3+ | | **Branch** | develop on `dev`, merge to `main` (protected) | +| **Wiki** | [MokoSuiteLogistics Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteLogistics/wiki) | ## Architecture -Joomla **package** -- Layer 2 add-on. CRM contacts as shippers/consignees, shipment tracking with multi-stop routes, warehouse zone management. +Joomla **package** -- Layer 2 add-on. CRM contacts as customers/drivers, route-based dispatch with proof of delivery. ## Rules diff --git a/README.md b/README.md index 406e9c9..54bdbc5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,90 @@ -# MokoSuiteLogistics + -MokoSuite Logistics — delivery management, route optimization, courier dispatch, proof of delivery for Joomla 6 \ No newline at end of file +# MokoSuite Logistics + +Delivery management, route optimization, courier dispatch, and proof of delivery for MokoSuite on Joomla 6. + +## Overview + +MokoSuiteLogistics is a **Layer 2** extension in the MokoSuite platform, building on MokoSuiteClient (Layer 0) and MokoSuiteCRM (Layer 1) to provide complete logistics and delivery operations management. Customers and drivers are CRM contacts -- no duplicate user tables. + +## Package Contents + +| Extension | Type | Description | +|---|---|---| +| `plg_system_mokosuitelogistics` | System Plugin | Core helpers, SQL schema, service classes | +| `com_mokosuitelogistics` | Component | Admin dashboard, list views, configuration | +| `plg_webservices_mokosuitelogistics` | Webservices Plugin | REST API endpoints | + +## Features + +- **Order Management** -- standard, express, same-day, scheduled, and bulk delivery types with full status lifecycle +- **Delivery Tracking** -- real-time delivery status with attempt tracking and failure reasons +- **Route Optimization** -- planned routes with sequenced stops, distance tracking, and completion status +- **Warehouse Management** -- multiple warehouse locations with manager assignments +- **Driver Management** -- CRM contact-linked profiles, vehicle descriptions, rating aggregation +- **Pricing Rules** -- configurable per order type with base fees, per-km/kg rates, express multipliers +- **Proof of Delivery** -- signature capture, photo proof, geolocation verification +- **REST API** -- full CRUD for orders, deliveries, routes, warehouses, pricing rules, drivers, and proofs + +## Database Schema + +8 tables covering the full logistics domain: + +| Table | Purpose | +|---|---| +| `#__mokosuitelogistics_orders` | Order lifecycle with customer, address, package, payment details | +| `#__mokosuitelogistics_deliveries` | Delivery assignments with driver, route, timestamps, attempts | +| `#__mokosuitelogistics_routes` | Planned delivery routes with distance and stop counts | +| `#__mokosuitelogistics_route_stops` | Sequenced stops within routes with arrival tracking | +| `#__mokosuitelogistics_delivery_proofs` | Signature, photo, and geolocation proof of delivery | +| `#__mokosuitelogistics_pricing_rules` | Fee structures per order type | +| `#__mokosuitelogistics_drivers` | Driver profiles linked to CRM contacts | +| `#__mokosuitelogistics_warehouses` | Warehouse locations with manager contacts | + +## Order Status Flow + +``` +pending --> confirmed --> assigned --> picked_up --> in_transit --> delivered + | | | | | + +--> cancelled +--> cancelled +--> failed +--> failed +--> failed + | + +--> returned +``` + +## Requirements + +- Joomla 6.x +- PHP 8.3+ +- MokoSuiteClient (Layer 0) +- MokoSuiteCRM (Layer 1) + +## Installation + +Install via Joomla Extension Manager using the package file `pkg_mokosuitelogistics.zip`. The package installs all three extensions (system plugin, component, webservices plugin) in the correct order. + +Updates are delivered automatically via the [MokoGitea update server](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteLogistics/updates.xml). + +## Configuration + +Settings are managed via the system plugin parameters: + +| Fieldset | Key Settings | +|---|---| +| **Basic** | Company name, default currency, timezone, distance unit | +| **Delivery** | Max delivery radius, default time window, auto-assign | +| **Pricing** | Base delivery fee, per-distance rate, express multiplier, minimum charge | +| **Notifications** | Order confirmation, dispatch notification, delivery proof | + +## License + +GNU General Public License v3.0 or later. + +## Links + +- [Documentation](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteLogistics/wiki) +- [Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteLogistics/issues) +- [MokoSuite Platform](https://mokoconsulting.tech) diff --git a/source/packages/com_mokosuitelogistics/admin/access.xml b/source/packages/com_mokosuitelogistics/admin/access.xml index 98f1236..57b209e 100644 --- a/source/packages/com_mokosuitelogistics/admin/access.xml +++ b/source/packages/com_mokosuitelogistics/admin/access.xml @@ -1,11 +1,20 @@ -
- - - - - - -
+
+ + + + + + + + + + + + + + + +
diff --git a/source/packages/com_mokosuitelogistics/admin/config.xml b/source/packages/com_mokosuitelogistics/admin/config.xml index ddda8e7..5160607 100644 --- a/source/packages/com_mokosuitelogistics/admin/config.xml +++ b/source/packages/com_mokosuitelogistics/admin/config.xml @@ -1,6 +1,40 @@ -
- -
+
+ + + + + + + +
+
+ + + + + + +
+
+ + + + +
+
+ + + + + + + + + + + + +
diff --git a/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.ini b/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.ini index 2660541..332e072 100644 --- a/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.ini +++ b/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.ini @@ -1,8 +1,11 @@ -COM_MOKOSUITELOGISTICS="MokoSuiteLogistics" -COM_MOKOSUITELOGISTICS_DESCRIPTION="Layer 2 — Fleet logistics, shipment tracking, route planning, warehouse management" -COM_MOKOSUITELOGISTICS_LOGISTICSDASHBOARD="Dashboard" -COM_MOKOSUITELOGISTICS_LOGISTICSSHIPMENTS="Shipments" -COM_MOKOSUITELOGISTICS_LOGISTICSROUTES="Routes" -COM_MOKOSUITELOGISTICS_LOGISTICSCARRIERS="Carriers" -COM_MOKOSUITELOGISTICS_LOGISTICSWAREHOUSES="Warehouses" -COM_MOKOSUITELOGISTICS_LOGISTICSPACKAGES="Packages" +; Copyright (C) 2026 Moko Consulting +; SPDX-License-Identifier: GPL-3.0-or-later +COM_MOKOSUITELOGISTICS="MokoSuite Logistics" +COM_MOKOSUITELOGISTICS_DASHBOARD="Dashboard" +COM_MOKOSUITELOGISTICS_ORDERS="Orders" +COM_MOKOSUITELOGISTICS_DELIVERIES="Deliveries" +COM_MOKOSUITELOGISTICS_ROUTES="Routes" +COM_MOKOSUITELOGISTICS_WAREHOUSES="Warehouses" +COM_MOKOSUITELOGISTICS_PRICING="Pricing" +COM_MOKOSUITELOGISTICS_DRIVERS="Drivers" +COM_MOKOSUITELOGISTICS_PROOFS="Proof of Delivery" diff --git a/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.sys.ini b/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.sys.ini index 844c238..6c1d38d 100644 --- a/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.sys.ini +++ b/source/packages/com_mokosuitelogistics/admin/language/en-GB/com_mokosuitelogistics.sys.ini @@ -1,2 +1,4 @@ -COM_MOKOSUITELOGISTICS="MokoSuiteLogistics" -COM_MOKOSUITELOGISTICS_DESCRIPTION="Layer 2 — Fleet logistics, shipment tracking, route planning, warehouse management" +; Copyright (C) 2026 Moko Consulting +; SPDX-License-Identifier: GPL-3.0-or-later +COM_MOKOSUITELOGISTICS="MokoSuite Logistics" +COM_MOKOSUITELOGISTICS_XML_DESCRIPTION="Delivery management, route optimization, courier dispatch, proof of delivery" diff --git a/source/packages/com_mokosuitelogistics/admin/services/provider.php b/source/packages/com_mokosuitelogistics/admin/services/provider.php index a7e02a6..0b635f5 100644 --- a/source/packages/com_mokosuitelogistics/admin/services/provider.php +++ b/source/packages/com_mokosuitelogistics/admin/services/provider.php @@ -1,30 +1,28 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ defined('_JEXEC') or die; -use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface; use Joomla\CMS\Extension\ComponentInterface; use Joomla\CMS\Extension\MVCComponent; +use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; -use Joomla\CMS\Router\ApiRouter; +use Joomla\CMS\Component\Router\RouterFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; -return new class implements ServiceProviderInterface -{ - public function register(Container $container): void - { - $container->set( - ComponentInterface::class, - function (Container $container) { - $component = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class)); - $component->setMVCFactory($container->get(MVCFactoryInterface::class)); - return $component; - } - ); - } +return new class implements ServiceProviderInterface { + public function register(Container $container): void { + $container->set(ComponentInterface::class, function (Container $container) { + $c = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class)); + $c->setMVCFactory($container->get(MVCFactoryInterface::class)); + $c->setRouterFactory($container->get(RouterFactoryInterface::class)); + return $c; + }); + } }; diff --git a/source/packages/com_mokosuitelogistics/admin/src/Controller/DisplayController.php b/source/packages/com_mokosuitelogistics/admin/src/Controller/DisplayController.php index 99044bd..40a2313 100644 --- a/source/packages/com_mokosuitelogistics/admin/src/Controller/DisplayController.php +++ b/source/packages/com_mokosuitelogistics/admin/src/Controller/DisplayController.php @@ -1,10 +1,12 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ -namespace MokoConsulting\Component\MokoSuiteLogistics\Administrator\Controller; +namespace Moko\Component\MokoSuiteLogistics\Administrator\Controller; defined('_JEXEC') or die; @@ -12,5 +14,5 @@ use Joomla\CMS\MVC\Controller\BaseController; class DisplayController extends BaseController { - protected $default_view = 'logisticsdashboard'; + protected $default_view = 'logisticsdashboard'; } diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/DeliveriesModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/DeliveriesModel.php new file mode 100644 index 0000000..5b00d10 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/DeliveriesModel.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class DeliveriesModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__mokosuitelogistics_deliveries', 'a')) + ->order($db->escape($this->getState('list.ordering', 'a.created')) + . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + return $query; + } + + protected function populateState($ordering = 'a.created', $direction = 'DESC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/DriversModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/DriversModel.php new file mode 100644 index 0000000..c00cf3a --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/DriversModel.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class DriversModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__mokosuitelogistics_drivers', 'a')) + ->order($db->escape($this->getState('list.ordering', 'a.name')) + . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + protected function populateState($ordering = 'a.name', $direction = 'ASC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/LogisticsDashboardModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/LogisticsDashboardModel.php index e4894d3..2715da3 100644 --- a/source/packages/com_mokosuitelogistics/admin/src/Model/LogisticsDashboardModel.php +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/LogisticsDashboardModel.php @@ -1,15 +1,22 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ -namespace MokoConsulting\Component\MokoSuiteLogistics\Administrator\Model; +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; defined('_JEXEC') or die; use Joomla\CMS\MVC\Model\BaseDatabaseModel; +use Moko\Plugin\System\MokoSuiteLogistics\Helper\LogisticsHelper; class LogisticsDashboardModel extends BaseDatabaseModel { + public function getDashboard(): object + { + return LogisticsHelper::getDashboard(); + } } diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/OrdersModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/OrdersModel.php new file mode 100644 index 0000000..2540221 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/OrdersModel.php @@ -0,0 +1,52 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class OrdersModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select([ + 'o.*', + 'd.name AS driver_name', + ]) + ->from($db->quoteName('#__mokosuitelogistics_orders', 'o')) + ->join('LEFT', $db->quoteName('#__mokosuitelogistics_deliveries', 'del') . ' ON del.order_id = o.id') + ->join('LEFT', $db->quoteName('#__mokosuitelogistics_drivers', 'd') . ' ON d.id = del.driver_id'); + + $search = $this->getState('filter.search'); + if ($search) { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(o.order_ref LIKE ' . $search . ' OR o.customer_name LIKE ' . $search . ')'); + } + + $status = $this->getState('filter.status'); + if ($status) { + $query->where($db->quoteName('o.status') . ' = ' . $db->quote($status)); + } + + $query->order($db->escape($this->getState('list.ordering', 'o.created')) + . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + return $query; + } + + protected function populateState($ordering = 'o.created', $direction = 'DESC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/PricingRulesModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/PricingRulesModel.php new file mode 100644 index 0000000..ca45db8 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/PricingRulesModel.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class PricingRulesModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__mokosuitelogistics_pricing_rules', 'a')) + ->order($db->escape($this->getState('list.ordering', 'a.name')) + . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + protected function populateState($ordering = 'a.name', $direction = 'ASC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/ProofsModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/ProofsModel.php new file mode 100644 index 0000000..93c3203 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/ProofsModel.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class ProofsModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__mokosuitelogistics_delivery_proofs', 'a')) + ->order($db->escape($this->getState('list.ordering', 'a.created')) + . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + return $query; + } + + protected function populateState($ordering = 'a.created', $direction = 'DESC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/RoutesModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/RoutesModel.php new file mode 100644 index 0000000..0a9ef54 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/RoutesModel.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class RoutesModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__mokosuitelogistics_routes', 'a')) + ->order($db->escape($this->getState('list.ordering', 'a.created')) + . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + return $query; + } + + protected function populateState($ordering = 'a.created', $direction = 'DESC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/Model/WarehousesModel.php b/source/packages/com_mokosuitelogistics/admin/src/Model/WarehousesModel.php new file mode 100644 index 0000000..ae745b3 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/Model/WarehousesModel.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\Model; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +class WarehousesModel extends ListModel +{ + protected function getListQuery(): QueryInterface + { + $db = $this->getDatabase(); + + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__mokosuitelogistics_warehouses', 'a')) + ->order($db->escape($this->getState('list.ordering', 'a.name')) + . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + protected function populateState($ordering = 'a.name', $direction = 'ASC'): void + { + parent::populateState($ordering, $direction); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/Deliveries/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/Deliveries/HtmlView.php new file mode 100644 index 0000000..7fbed60 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/Deliveries/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\Deliveries; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Deliveries'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/Drivers/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/Drivers/HtmlView.php new file mode 100644 index 0000000..06fa87b --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/Drivers/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\Drivers; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Drivers'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/LogisticsDashboard/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/LogisticsDashboard/HtmlView.php index 534e0cb..fb15c4e 100644 --- a/source/packages/com_mokosuitelogistics/admin/src/View/LogisticsDashboard/HtmlView.php +++ b/source/packages/com_mokosuitelogistics/admin/src/View/LogisticsDashboard/HtmlView.php @@ -1,10 +1,12 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ -namespace MokoConsulting\Component\MokoSuiteLogistics\Administrator\View\LogisticsDashboard; +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\LogisticsDashboard; defined('_JEXEC') or die; @@ -13,9 +15,15 @@ use Joomla\CMS\Toolbar\ToolbarHelper; class HtmlView extends BaseHtmlView { - public function display($tpl = null): void - { - ToolbarHelper::title('Dashboard', 'generic'); - parent::display($tpl); - } + protected object $dashboard; + + public function display($tpl = null): void + { + $this->dashboard = $this->get('Dashboard'); + + ToolbarHelper::title('MokoSuite Logistics - Dashboard'); + ToolbarHelper::preferences('com_mokosuitelogistics'); + + parent::display($tpl); + } } diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/Orders/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/Orders/HtmlView.php new file mode 100644 index 0000000..4d37865 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/Orders/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\Orders; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Orders'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/PricingRules/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/PricingRules/HtmlView.php new file mode 100644 index 0000000..b8f0bd6 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/PricingRules/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\PricingRules; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Pricing Rules'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/Proofs/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/Proofs/HtmlView.php new file mode 100644 index 0000000..32542cb --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/Proofs/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\Proofs; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Proof of Delivery'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/Routes/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/Routes/HtmlView.php new file mode 100644 index 0000000..7b75be7 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/Routes/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\Routes; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Routes'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/src/View/Warehouses/HtmlView.php b/source/packages/com_mokosuitelogistics/admin/src/View/Warehouses/HtmlView.php new file mode 100644 index 0000000..224b032 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/src/View/Warehouses/HtmlView.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +namespace Moko\Component\MokoSuiteLogistics\Administrator\View\Warehouses; + +defined('_JEXEC') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\ToolbarHelper; + +class HtmlView extends BaseHtmlView +{ + protected array $items = []; + protected mixed $pagination = null; + protected mixed $state = null; + + public function display($tpl = null): void + { + $this->items = $this->get('Items') ?: []; + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + ToolbarHelper::title('MokoSuite Logistics - Warehouses'); + + parent::display($tpl); + } +} diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/deliveries/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/deliveries/default.php new file mode 100644 index 0000000..9665e41 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/deliveries/default.php @@ -0,0 +1,14 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; +?> +
+

Deliveries

+

Coming soon.

+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/drivers/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/drivers/default.php new file mode 100644 index 0000000..2a771ad --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/drivers/default.php @@ -0,0 +1,14 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; +?> +
+

Drivers

+

Coming soon.

+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/logisticsdashboard/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/logisticsdashboard/default.php index 589a88f..404092c 100644 --- a/source/packages/com_mokosuitelogistics/admin/tmpl/logisticsdashboard/default.php +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/logisticsdashboard/default.php @@ -1,15 +1,62 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ defined('_JEXEC') or die; +$d = $this->dashboard; ?> -
-
-

Dashboard

-

Manage dashboard here.

+
+
+
+
+
Total Orders
+

total_orders; ?>

+
+
+
+
+
+
+
Active Deliveries
+

active_deliveries; ?>

+
+
+
+
+
+
+
Available Drivers
+

available_drivers; ?>

+
+
+
+
+
+
+
Total Drivers
+

total_drivers; ?>

+
+
+
+
+
+
+
Total Warehouses
+

total_warehouses; ?>

+
+
+
+
+
+
+
Today's Revenue
+

today_revenue, 2); ?>

+
+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/orders/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/orders/default.php new file mode 100644 index 0000000..a474a20 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/orders/default.php @@ -0,0 +1,68 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Router\Route; + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +$statusBadges = [ + 'pending' => 'secondary', + 'confirmed' => 'info', + 'assigned' => 'warning', + 'picked_up' => 'primary', + 'in_transit' => 'primary', + 'delivered' => 'success', + 'failed' => 'danger', + 'cancelled' => 'danger', + 'returned' => 'dark', +]; +?> +
+
+ + + + + + + + + + + + + + + items as $i => $item) : + $badge = $statusBadges[$item->status] ?? 'secondary'; + ?> + + + + + + + + + + + + +
#StatusCustomerDriverPickup
pagination->getRowOffset($i); ?>escape($item->order_ref); ?>escape($item->status); ?>escape($item->customer_name); ?>escape($item->driver_name ?? ''); ?>escape($item->pickup_address); ?>delivery_fee ? number_format((float) $item->delivery_fee, 2) : '-'; ?>created, 'Y-m-d H:i'); ?>
+ + pagination->getListFooter(); ?> + + + + +
+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/pricingrules/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/pricingrules/default.php new file mode 100644 index 0000000..8a8aac7 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/pricingrules/default.php @@ -0,0 +1,14 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; +?> +
+

Pricing Rules

+

Coming soon.

+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/proofs/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/proofs/default.php new file mode 100644 index 0000000..8d0b1cd --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/proofs/default.php @@ -0,0 +1,14 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; +?> +
+

Proof of Delivery

+

Coming soon.

+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/routes/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/routes/default.php new file mode 100644 index 0000000..93929b7 --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/routes/default.php @@ -0,0 +1,14 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; +?> +
+

Routes

+

Coming soon.

+
diff --git a/source/packages/com_mokosuitelogistics/admin/tmpl/warehouses/default.php b/source/packages/com_mokosuitelogistics/admin/tmpl/warehouses/default.php new file mode 100644 index 0000000..44c55ed --- /dev/null +++ b/source/packages/com_mokosuitelogistics/admin/tmpl/warehouses/default.php @@ -0,0 +1,14 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +defined('_JEXEC') or die; +?> +
+

Warehouses

+

Coming soon.

+
diff --git a/source/packages/com_mokosuitelogistics/mokosuitelogistics.xml b/source/packages/com_mokosuitelogistics/mokosuitelogistics.xml index 0179e6e..d42a347 100644 --- a/source/packages/com_mokosuitelogistics/mokosuitelogistics.xml +++ b/source/packages/com_mokosuitelogistics/mokosuitelogistics.xml @@ -1,32 +1,38 @@ - com_mokosuitelogistics - 0.0.0 - 2026-06 - Moko Consulting - hello@mokoconsulting.tech - https://mokoconsulting.tech - (C) 2026 Moko Consulting - GPL-3.0-or-later - Layer 2 — Fleet logistics, shipment tracking, route planning, warehouse management - MokoConsulting\Component\MokoSuiteLogistics - - - services - src - tmpl - language - access.xml - config.xml - - MokoSuiteLogistics - - Dashboard - Shipments - Routes - Carriers - Warehouses - Packages - - + MokoSuite Logistics + Moko Consulting + hello@mokoconsulting.tech + https://mokoconsulting.tech + 2026-06-27 + Copyright (C) 2026 Moko Consulting. + GPL-3.0-or-later + 06.00.00 + Delivery management, route optimization, courier dispatch, proof of delivery + Moko\Component\MokoSuiteLogistics + + + access.xml + config.xml + language + services + src + tmpl + + + en-GB/com_mokosuitelogistics.ini + en-GB/com_mokosuitelogistics.sys.ini + + COM_MOKOSUITELOGISTICS + + COM_MOKOSUITELOGISTICS_DASHBOARD + COM_MOKOSUITELOGISTICS_ORDERS + COM_MOKOSUITELOGISTICS_DELIVERIES + COM_MOKOSUITELOGISTICS_ROUTES + COM_MOKOSUITELOGISTICS_WAREHOUSES + COM_MOKOSUITELOGISTICS_PRICING + COM_MOKOSUITELOGISTICS_DRIVERS + COM_MOKOSUITELOGISTICS_PROOFS + + diff --git a/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.ini b/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.ini index d8af8a0..1fab730 100644 --- a/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.ini +++ b/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.ini @@ -1,3 +1,2 @@ -PLG_SYSTEM_MOKOSUITELOGISTICS="Logistics" -PLG_SYSTEM_MOKOSUITELOGISTICS_DESCRIPTION="MokoSuiteLogistics system plugin" -PLG_SYSTEM_MOKOSUITELOGISTICS_ENABLED="Enable MokoSuiteLogistics" +PLG_SYSTEM_MOKOSUITELOGISTICS="System - MokoSuite Logistics" +PLG_SYSTEM_MOKOSUITELOGISTICS_DESC="Delivery management, route optimization, courier dispatch, proof of delivery" diff --git a/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.sys.ini b/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.sys.ini index d8af8a0..1fab730 100644 --- a/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.sys.ini +++ b/source/packages/plg_system_mokosuitelogistics/language/en-GB/plg_system_mokosuitelogistics.sys.ini @@ -1,3 +1,2 @@ -PLG_SYSTEM_MOKOSUITELOGISTICS="Logistics" -PLG_SYSTEM_MOKOSUITELOGISTICS_DESCRIPTION="MokoSuiteLogistics system plugin" -PLG_SYSTEM_MOKOSUITELOGISTICS_ENABLED="Enable MokoSuiteLogistics" +PLG_SYSTEM_MOKOSUITELOGISTICS="System - MokoSuite Logistics" +PLG_SYSTEM_MOKOSUITELOGISTICS_DESC="Delivery management, route optimization, courier dispatch, proof of delivery" diff --git a/source/packages/plg_system_mokosuitelogistics/mokosuitelogistics.xml b/source/packages/plg_system_mokosuitelogistics/mokosuitelogistics.xml index 7b93a00..20300c7 100644 --- a/source/packages/plg_system_mokosuitelogistics/mokosuitelogistics.xml +++ b/source/packages/plg_system_mokosuitelogistics/mokosuitelogistics.xml @@ -1,43 +1,68 @@ - plg_system_mokosuitelogistics - 0.0.0 - 2026-06 - Moko Consulting - hello@mokoconsulting.tech - https://mokoconsulting.tech - (C) 2026 Moko Consulting - GPL-3.0-or-later - MokoSuiteLogistics system plugin -- schema owner and bootstrap - MokoConsulting\Plugin\System\MokoSuiteLogistics - - src - services - sql - language - - - - sql/install.mysql.sql - - - - - sql/uninstall.mysql.sql - - - - en-GB/plg_system_mokosuitelogistics.ini - en-GB/plg_system_mokosuitelogistics.sys.ini - - - -
- - - - -
-
-
+ System - MokoSuite Logistics + mokosuitelogistics + Moko Consulting + 2026-06-27 + Copyright (C) 2026 Moko Consulting. All rights reserved. + GPL-3.0-or-later + hello@mokoconsulting.tech + https://mokoconsulting.tech + 06.00.00 + 8.3 + PLG_SYSTEM_MOKOSUITELOGISTICS_DESC + Moko\Plugin\System\MokoSuiteLogistics + + src + services + language + sql + + + en-GB/plg_system_mokosuitelogistics.ini + en-GB/plg_system_mokosuitelogistics.sys.ini + + sql/install.mysql.sql + sql/uninstall.mysql.sql + + +
+ + + + + + + +
+
+ + + + + + +
+
+ + + + +
+
+ + + + + + + + + + + + +
+
+
diff --git a/source/packages/plg_system_mokosuitelogistics/services/provider.php b/source/packages/plg_system_mokosuitelogistics/services/provider.php index 281d8e8..1fbda3d 100644 --- a/source/packages/plg_system_mokosuitelogistics/services/provider.php +++ b/source/packages/plg_system_mokosuitelogistics/services/provider.php @@ -1,7 +1,9 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ defined('_JEXEC') or die; @@ -12,20 +14,20 @@ use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; -use MokoConsulting\Plugin\System\MokoSuiteLogistics\Extension\Logistics; +use Moko\Plugin\System\MokoSuiteLogistics\Extension\Logistics; return new class implements ServiceProviderInterface { - public function register(Container $container): void - { - $container->set( - PluginInterface::class, - function (Container $container) { - $dispatcher = $container->get(DispatcherInterface::class); - $plugin = new Logistics($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuitelogistics')); - $plugin->setApplication(Factory::getApplication()); - return $plugin; - } - ); - } + public function register(Container $container): void + { + $container->set( + PluginInterface::class, + function (Container $container) { + $dispatcher = $container->get(DispatcherInterface::class); + $plugin = new Logistics($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuitelogistics')); + $plugin->setApplication(Factory::getApplication()); + return $plugin; + } + ); + } }; diff --git a/source/packages/plg_system_mokosuitelogistics/sql/install.mysql.sql b/source/packages/plg_system_mokosuitelogistics/sql/install.mysql.sql index 7043444..ed34a05 100644 --- a/source/packages/plg_system_mokosuitelogistics/sql/install.mysql.sql +++ b/source/packages/plg_system_mokosuitelogistics/sql/install.mysql.sql @@ -1,172 +1,155 @@ --- MokoSuiteLogistics Schema --- Copyright (C) 2026 Moko Consulting --- SPDX-License-Identifier: GPL-3.0-or-later +CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_orders` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `order_ref` VARCHAR(20) NOT NULL, + `customer_contact_id` INT DEFAULT NULL, + `customer_name` VARCHAR(255) NOT NULL, + `customer_phone` VARCHAR(50) NOT NULL DEFAULT '', + `customer_email` VARCHAR(255) NOT NULL DEFAULT '', + `status` ENUM('pending','confirmed','assigned','picked_up','in_transit','delivered','failed','cancelled','returned') NOT NULL DEFAULT 'pending', + `order_type` ENUM('standard','express','same_day','scheduled','bulk') NOT NULL DEFAULT 'standard', + `pickup_address` VARCHAR(500) NOT NULL, + `pickup_lat` DECIMAL(10,7) DEFAULT NULL, + `pickup_lng` DECIMAL(10,7) DEFAULT NULL, + `delivery_address` VARCHAR(500) NOT NULL, + `delivery_lat` DECIMAL(10,7) DEFAULT NULL, + `delivery_lng` DECIMAL(10,7) DEFAULT NULL, + `package_type` ENUM('envelope','small_box','medium_box','large_box','pallet','fragile','perishable','custom') NOT NULL DEFAULT 'small_box', + `weight_kg` DECIMAL(8,2) DEFAULT NULL, + `estimated_distance_km` DECIMAL(10,2) DEFAULT NULL, + `delivery_fee` DECIMAL(10,2) NOT NULL DEFAULT 0.00, + `total_charge` DECIMAL(10,2) NOT NULL DEFAULT 0.00, + `payment_method` ENUM('cash','card','account','prepaid','cod') NOT NULL DEFAULT 'card', + `payment_status` ENUM('pending','paid','refunded','failed') NOT NULL DEFAULT 'pending', + `notes` TEXT, + `created` DATETIME NOT NULL, + `created_by` INT NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE KEY `idx_ref` (`order_ref`), + KEY `idx_customer` (`customer_contact_id`), + KEY `idx_status` (`status`), + KEY `idx_type` (`order_type`), + KEY `idx_created` (`created`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_carriers` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `contact_id` INT UNSIGNED NULL COMMENT 'FK to CRM contacts', - `name` VARCHAR(255) NOT NULL, - `code` VARCHAR(50) NOT NULL, - `carrier_type` ENUM('ground','air','sea','rail','courier') NOT NULL DEFAULT 'ground', - `tracking_url_template` VARCHAR(500) NULL, - `phone` VARCHAR(50) NULL, - `email` VARCHAR(255) NULL, - `status` ENUM('active','inactive','suspended') NOT NULL DEFAULT 'active', - `notes` TEXT NULL, - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modified` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_code` (`code`), - KEY `idx_status` (`status`), - KEY `idx_contact` (`contact_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - -CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_warehouses` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `name` VARCHAR(255) NOT NULL, - `code` VARCHAR(50) NOT NULL, - `address` TEXT NULL, - `city` VARCHAR(100) NULL, - `state` VARCHAR(100) NULL, - `postal_code` VARCHAR(20) NULL, - `country` VARCHAR(100) NULL, - `capacity_sqft` DECIMAL(12,2) NULL, - `manager_contact_id` INT UNSIGNED NULL COMMENT 'FK to CRM contacts', - `status` ENUM('active','inactive','maintenance') NOT NULL DEFAULT 'active', - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modified` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_code` (`code`), - KEY `idx_status` (`status`), - KEY `idx_manager_contact` (`manager_contact_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - -CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_warehouse_zones` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `warehouse_id` INT UNSIGNED NOT NULL, - `name` VARCHAR(255) NOT NULL, - `zone_type` ENUM('receiving','storage','picking','packing','shipping','cold','hazmat') NOT NULL DEFAULT 'storage', - `capacity` INT UNSIGNED NULL, - `current_utilization` INT UNSIGNED NOT NULL DEFAULT 0, - `ordering` INT NOT NULL DEFAULT 0, - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modified` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `idx_warehouse` (`warehouse_id`), - KEY `idx_zone_type` (`zone_type`), - CONSTRAINT `fk_zone_warehouse` FOREIGN KEY (`warehouse_id`) REFERENCES `#__mokosuitelogistics_warehouses`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - -CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_shipments` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `shipment_number` VARCHAR(50) NOT NULL, - `shipper_contact_id` INT UNSIGNED NULL COMMENT 'FK to CRM contacts', - `consignee_contact_id` INT UNSIGNED NULL COMMENT 'FK to CRM contacts', - `carrier_id` INT UNSIGNED NULL, - `warehouse_id` INT UNSIGNED NULL, - `origin_address` TEXT NULL, - `destination_address` TEXT NULL, - `shipment_type` ENUM('inbound','outbound','transfer','return') NOT NULL DEFAULT 'outbound', - `status` ENUM('draft','booked','picked_up','in_transit','out_for_delivery','delivered','cancelled','returned') NOT NULL DEFAULT 'draft', - `priority` ENUM('standard','express','overnight','freight') NOT NULL DEFAULT 'standard', - `weight_kg` DECIMAL(10,3) NULL, - `volume_cbm` DECIMAL(10,4) NULL, - `estimated_pickup` DATETIME NULL, - `estimated_delivery` DATETIME NULL, - `actual_pickup` DATETIME NULL, - `actual_delivery` DATETIME NULL, - `tracking_number` VARCHAR(255) NULL, - `shipping_cost` DECIMAL(10,2) NULL, - `insurance_value` DECIMAL(10,2) NULL, - `notes` TEXT NULL, - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modified` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_shipment_number` (`shipment_number`), - KEY `idx_status` (`status`), - KEY `idx_shipper_contact` (`shipper_contact_id`), - KEY `idx_consignee_contact` (`consignee_contact_id`), - KEY `idx_carrier` (`carrier_id`), - KEY `idx_warehouse` (`warehouse_id`), - KEY `idx_estimated_delivery` (`estimated_delivery`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_deliveries` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `order_id` INT UNSIGNED NOT NULL, + `driver_id` INT UNSIGNED DEFAULT NULL, + `route_id` INT UNSIGNED DEFAULT NULL, + `status` ENUM('assigned','en_route_pickup','picked_up','en_route_delivery','delivered','failed','returned') NOT NULL DEFAULT 'assigned', + `assigned_at` DATETIME DEFAULT NULL, + `picked_up_at` DATETIME DEFAULT NULL, + `delivered_at` DATETIME DEFAULT NULL, + `failed_at` DATETIME DEFAULT NULL, + `failure_reason` VARCHAR(500) NOT NULL DEFAULT '', + `attempt_number` TINYINT UNSIGNED NOT NULL DEFAULT 1, + `actual_distance_km` DECIMAL(10,2) DEFAULT NULL, + `driver_notes` TEXT, + `created` DATETIME NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_order` (`order_id`), + KEY `idx_driver` (`driver_id`), + KEY `idx_route` (`route_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_routes` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `name` VARCHAR(255) NOT NULL, - `carrier_id` INT UNSIGNED NULL, - `route_type` ENUM('scheduled','on_demand','dedicated') NOT NULL DEFAULT 'scheduled', - `status` ENUM('active','inactive','planned') NOT NULL DEFAULT 'planned', - `distance_km` DECIMAL(10,2) NULL, - `estimated_duration_hours` DECIMAL(6,2) NULL, - `notes` TEXT NULL, - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modified` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `idx_carrier` (`carrier_id`), - KEY `idx_status` (`status`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `route_ref` VARCHAR(20) NOT NULL, + `driver_id` INT UNSIGNED DEFAULT NULL, + `status` ENUM('planned','active','completed','cancelled') NOT NULL DEFAULT 'planned', + `planned_date` DATE NOT NULL, + `started_at` DATETIME DEFAULT NULL, + `completed_at` DATETIME DEFAULT NULL, + `total_stops` INT UNSIGNED NOT NULL DEFAULT 0, + `total_distance_km` DECIMAL(10,2) NOT NULL DEFAULT 0.00, + `notes` TEXT, + `created` DATETIME NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `idx_ref` (`route_ref`), + KEY `idx_driver` (`driver_id`), + KEY `idx_status` (`status`), + KEY `idx_date` (`planned_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_route_stops` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `route_id` INT UNSIGNED NOT NULL, - `stop_number` INT UNSIGNED NOT NULL, - `location_name` VARCHAR(255) NOT NULL, - `address` TEXT NULL, - `latitude` DECIMAL(10,7) NULL, - `longitude` DECIMAL(10,7) NULL, - `stop_type` ENUM('pickup','dropoff','waypoint','rest') NOT NULL DEFAULT 'dropoff', - `estimated_arrival` DATETIME NULL, - `estimated_departure` DATETIME NULL, - `actual_arrival` DATETIME NULL, - `actual_departure` DATETIME NULL, - `notes` TEXT NULL, - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `idx_route` (`route_id`), - KEY `idx_stop_number` (`route_id`, `stop_number`), - CONSTRAINT `fk_stop_route` FOREIGN KEY (`route_id`) REFERENCES `#__mokosuitelogistics_routes`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `route_id` INT UNSIGNED NOT NULL, + `order_id` INT UNSIGNED DEFAULT NULL, + `stop_type` ENUM('pickup','delivery','warehouse','return') NOT NULL DEFAULT 'delivery', + `address` VARCHAR(500) NOT NULL, + `lat` DECIMAL(10,7) DEFAULT NULL, + `lng` DECIMAL(10,7) DEFAULT NULL, + `sequence_order` INT UNSIGNED NOT NULL DEFAULT 0, + `estimated_arrival` DATETIME DEFAULT NULL, + `actual_arrival` DATETIME DEFAULT NULL, + `status` ENUM('pending','arrived','completed','skipped') NOT NULL DEFAULT 'pending', + `notes` TEXT, + PRIMARY KEY (`id`), + KEY `idx_route` (`route_id`), + KEY `idx_order` (`order_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_packages` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `shipment_id` INT UNSIGNED NOT NULL, - `package_number` VARCHAR(50) NOT NULL, - `description` VARCHAR(255) NULL, - `weight_kg` DECIMAL(10,3) NULL, - `length_cm` DECIMAL(8,2) NULL, - `width_cm` DECIMAL(8,2) NULL, - `height_cm` DECIMAL(8,2) NULL, - `declared_value` DECIMAL(10,2) NULL, - `is_fragile` TINYINT(1) NOT NULL DEFAULT 0, - `is_hazmat` TINYINT(1) NOT NULL DEFAULT 0, - `barcode` VARCHAR(255) NULL, - `status` ENUM('created','labeled','in_transit','delivered','damaged','lost') NOT NULL DEFAULT 'created', - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `modified` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_package_number` (`package_number`), - KEY `idx_shipment` (`shipment_id`), - KEY `idx_status` (`status`), - KEY `idx_barcode` (`barcode`), - CONSTRAINT `fk_package_shipment` FOREIGN KEY (`shipment_id`) REFERENCES `#__mokosuitelogistics_shipments`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_delivery_proofs` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `delivery_id` INT UNSIGNED NOT NULL, + `proof_type` ENUM('signature','photo','both') NOT NULL DEFAULT 'photo', + `recipient_name` VARCHAR(255) NOT NULL DEFAULT '', + `signature_data` TEXT, + `photo_path` VARCHAR(500) NOT NULL DEFAULT '', + `geolocation_lat` DECIMAL(10,7) DEFAULT NULL, + `geolocation_lng` DECIMAL(10,7) DEFAULT NULL, + `notes` TEXT, + `created` DATETIME NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_delivery` (`delivery_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_tracking_events` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `shipment_id` INT UNSIGNED NOT NULL, - `package_id` INT UNSIGNED NULL, - `event_type` ENUM('created','picked_up','in_transit','at_hub','out_for_delivery','delivered','exception','returned') NOT NULL, - `location` VARCHAR(255) NULL, - `latitude` DECIMAL(10,7) NULL, - `longitude` DECIMAL(10,7) NULL, - `description` TEXT NULL, - `event_time` DATETIME NOT NULL, - `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `idx_shipment` (`shipment_id`), - KEY `idx_package` (`package_id`), - KEY `idx_event_type` (`event_type`), - KEY `idx_event_time` (`event_time`), - CONSTRAINT `fk_tracking_shipment` FOREIGN KEY (`shipment_id`) REFERENCES `#__mokosuitelogistics_shipments`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_pricing_rules` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `order_type` ENUM('standard','express','same_day','scheduled','bulk','all') NOT NULL DEFAULT 'all', + `base_fee` DECIMAL(10,2) NOT NULL DEFAULT 5.00, + `per_km` DECIMAL(10,2) NOT NULL DEFAULT 1.00, + `per_kg` DECIMAL(10,2) NOT NULL DEFAULT 0.50, + `minimum_charge` DECIMAL(10,2) NOT NULL DEFAULT 5.00, + `express_multiplier` DECIMAL(4,2) NOT NULL DEFAULT 1.50, + `published` TINYINT NOT NULL DEFAULT 1, + `created` DATETIME NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_order_type` (`order_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_drivers` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `contact_id` INT DEFAULT NULL, + `name` VARCHAR(255) NOT NULL, + `phone` VARCHAR(50) NOT NULL DEFAULT '', + `email` VARCHAR(255) NOT NULL DEFAULT '', + `license_number` VARCHAR(50) NOT NULL DEFAULT '', + `vehicle_description` VARCHAR(255) NOT NULL DEFAULT '', + `status` ENUM('available','on_delivery','off_duty','inactive') NOT NULL DEFAULT 'available', + `current_lat` DECIMAL(10,7) DEFAULT NULL, + `current_lng` DECIMAL(10,7) DEFAULT NULL, + `rating` DECIMAL(3,2) NOT NULL DEFAULT 5.00, + `total_deliveries` INT UNSIGNED NOT NULL DEFAULT 0, + `published` TINYINT NOT NULL DEFAULT 1, + `created` DATETIME NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_contact` (`contact_id`), + KEY `idx_status` (`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `#__mokosuitelogistics_warehouses` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `address` VARCHAR(500) NOT NULL, + `lat` DECIMAL(10,7) DEFAULT NULL, + `lng` DECIMAL(10,7) DEFAULT NULL, + `manager_contact_id` INT DEFAULT NULL, + `phone` VARCHAR(50) NOT NULL DEFAULT '', + `published` TINYINT NOT NULL DEFAULT 1, + `created` DATETIME NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_manager` (`manager_contact_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/source/packages/plg_system_mokosuitelogistics/sql/uninstall.mysql.sql b/source/packages/plg_system_mokosuitelogistics/sql/uninstall.mysql.sql index 0f24cf1..a5258b5 100644 --- a/source/packages/plg_system_mokosuitelogistics/sql/uninstall.mysql.sql +++ b/source/packages/plg_system_mokosuitelogistics/sql/uninstall.mysql.sql @@ -1,8 +1,8 @@ -DROP TABLE IF EXISTS `#__mokosuitelogistics_tracking_events`; -DROP TABLE IF EXISTS `#__mokosuitelogistics_packages`; +DROP TABLE IF EXISTS `#__mokosuitelogistics_warehouses`; +DROP TABLE IF EXISTS `#__mokosuitelogistics_drivers`; +DROP TABLE IF EXISTS `#__mokosuitelogistics_pricing_rules`; +DROP TABLE IF EXISTS `#__mokosuitelogistics_delivery_proofs`; DROP TABLE IF EXISTS `#__mokosuitelogistics_route_stops`; DROP TABLE IF EXISTS `#__mokosuitelogistics_routes`; -DROP TABLE IF EXISTS `#__mokosuitelogistics_shipments`; -DROP TABLE IF EXISTS `#__mokosuitelogistics_warehouse_zones`; -DROP TABLE IF EXISTS `#__mokosuitelogistics_warehouses`; -DROP TABLE IF EXISTS `#__mokosuitelogistics_carriers`; +DROP TABLE IF EXISTS `#__mokosuitelogistics_deliveries`; +DROP TABLE IF EXISTS `#__mokosuitelogistics_orders`; diff --git a/source/packages/plg_system_mokosuitelogistics/src/Extension/Logistics.php b/source/packages/plg_system_mokosuitelogistics/src/Extension/Logistics.php index 44b061a..c01f14f 100644 --- a/source/packages/plg_system_mokosuitelogistics/src/Extension/Logistics.php +++ b/source/packages/plg_system_mokosuitelogistics/src/Extension/Logistics.php @@ -1,20 +1,24 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ -namespace MokoConsulting\Plugin\System\MokoSuiteLogistics\Extension; +namespace Moko\Plugin\System\MokoSuiteLogistics\Extension; defined('_JEXEC') or die; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\SubscriberInterface; -final class Logistics extends CMSPlugin implements SubscriberInterface +class Logistics extends CMSPlugin implements SubscriberInterface { - public static function getSubscribedEvents(): array - { - return []; - } + protected $autoloadLanguage = true; + + public static function getSubscribedEvents(): array + { + return []; + } } diff --git a/source/packages/plg_system_mokosuitelogistics/src/Helper/LogisticsHelper.php b/source/packages/plg_system_mokosuitelogistics/src/Helper/LogisticsHelper.php new file mode 100644 index 0000000..79d2ed0 --- /dev/null +++ b/source/packages/plg_system_mokosuitelogistics/src/Helper/LogisticsHelper.php @@ -0,0 +1,87 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting + */ + +declare(strict_types=1); + +namespace Moko\Plugin\System\MokoSuiteLogistics\Helper; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\Database\DatabaseInterface; + +class LogisticsHelper +{ + public static function getDashboard(): object + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + + $db->setQuery($db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mokosuitelogistics_orders')); + $totalOrders = (int) $db->loadResult(); + + $db->setQuery($db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mokosuitelogistics_deliveries') + ->where($db->quoteName('status') . ' IN (' . implode(',', array_map([$db, 'quote'], ['assigned', 'en_route_pickup', 'picked_up', 'en_route_delivery'])) . ')')); + $activeDeliveries = (int) $db->loadResult(); + + $db->setQuery($db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mokosuitelogistics_drivers') + ->where($db->quoteName('status') . ' = ' . $db->quote('available')) + ->where($db->quoteName('published') . ' = 1')); + $availableDrivers = (int) $db->loadResult(); + + $db->setQuery($db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mokosuitelogistics_drivers') + ->where($db->quoteName('published') . ' = 1')); + $totalDrivers = (int) $db->loadResult(); + + $db->setQuery($db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mokosuitelogistics_warehouses') + ->where($db->quoteName('published') . ' = 1')); + $totalWarehouses = (int) $db->loadResult(); + + $db->setQuery($db->getQuery(true) + ->select('COALESCE(SUM(' . $db->quoteName('total_charge') . '), 0)') + ->from('#__mokosuitelogistics_orders') + ->where($db->quoteName('status') . ' = ' . $db->quote('delivered')) + ->where($db->quoteName('payment_status') . ' = ' . $db->quote('paid')) + ->where('DATE(' . $db->quoteName('created') . ') = CURDATE()')); + $todayRevenue = (float) $db->loadResult(); + + return (object) [ + 'total_orders' => $totalOrders, + 'active_deliveries' => $activeDeliveries, + 'available_drivers' => $availableDrivers, + 'total_drivers' => $totalDrivers, + 'total_warehouses' => $totalWarehouses, + 'today_revenue' => $todayRevenue, + ]; + } + + public static function generateOrderRef(): string + { + $db = Factory::getContainer()->get(DatabaseInterface::class); + $prefix = 'LG'; + + do { + $ref = $prefix . strtoupper(bin2hex(random_bytes(4))); + $db->setQuery($db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mokosuitelogistics_orders') + ->where($db->quoteName('order_ref') . ' = ' . $db->quote($ref))); + } while ((int) $db->loadResult() > 0); + + return $ref; + } +} diff --git a/source/packages/plg_webservices_mokosuitelogistics/mokosuitelogistics.xml b/source/packages/plg_webservices_mokosuitelogistics/mokosuitelogistics.xml index 8b669b7..69d66b8 100644 --- a/source/packages/plg_webservices_mokosuitelogistics/mokosuitelogistics.xml +++ b/source/packages/plg_webservices_mokosuitelogistics/mokosuitelogistics.xml @@ -1,17 +1,15 @@ - + - plg_webservices_mokosuitelogistics - 0.0.0 - 2026-06 - Moko Consulting - hello@mokoconsulting.tech - https://mokoconsulting.tech - (C) 2026 Moko Consulting - GPL-3.0-or-later - MokoSuiteLogistics webservices plugin - MokoConsulting\Plugin\WebServices\MokoSuiteLogistics - - src - services - + Web Services - MokoSuite Logistics + mokosuitelogistics + Moko Consulting + hello@mokoconsulting.tech + https://mokoconsulting.tech + 2026-06-27 + Copyright (C) 2026 Moko Consulting. + 06.00.00 + GPL-3.0-or-later + REST API routes for MokoSuite Logistics delivery operations + Moko\Plugin\WebServices\MokoSuiteLogistics + srcservices diff --git a/source/packages/plg_webservices_mokosuitelogistics/services/provider.php b/source/packages/plg_webservices_mokosuitelogistics/services/provider.php index 751f8c0..26ce564 100644 --- a/source/packages/plg_webservices_mokosuitelogistics/services/provider.php +++ b/source/packages/plg_webservices_mokosuitelogistics/services/provider.php @@ -1,31 +1,24 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; -use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; -use MokoConsulting\Plugin\WebServices\MokoSuiteLogistics\Extension\MokoSuiteLogistics; +use Moko\Plugin\WebServices\MokoSuiteLogistics\Extension\MokoSuiteLogistics; -return new class implements ServiceProviderInterface -{ - public function register(Container $container): void - { - $container->set( - PluginInterface::class, - function (Container $container) { - $dispatcher = $container->get(DispatcherInterface::class); - $plugin = new MokoSuiteLogistics($dispatcher, (array) PluginHelper::getPlugin('webservices', 'mokosuitelogistics')); - $plugin->setApplication(Factory::getApplication()); - return $plugin; - } - ); - } +return new class implements ServiceProviderInterface { + public function register(Container $container): void { + $container->set(PluginInterface::class, function (Container $container) { + return new MokoSuiteLogistics($container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('webservices', 'mokosuitelogistics')); + }); + } }; diff --git a/source/packages/plg_webservices_mokosuitelogistics/src/Extension/MokoSuiteLogistics.php b/source/packages/plg_webservices_mokosuitelogistics/src/Extension/MokoSuiteLogistics.php index 09726a2..9948350 100644 --- a/source/packages/plg_webservices_mokosuitelogistics/src/Extension/MokoSuiteLogistics.php +++ b/source/packages/plg_webservices_mokosuitelogistics/src/Extension/MokoSuiteLogistics.php @@ -1,34 +1,36 @@ + * SPDX-License-Identifier: GPL-3.0-or-later + * Authored-by: Moko Consulting */ -namespace MokoConsulting\Plugin\WebServices\MokoSuiteLogistics\Extension; +namespace Moko\Plugin\WebServices\MokoSuiteLogistics\Extension; defined('_JEXEC') or die; use Joomla\CMS\Plugin\CMSPlugin; -use Joomla\CMS\Router\ApiRouter; use Joomla\Event\SubscriberInterface; -use Joomla\Router\Route; -final class MokoSuiteLogistics extends CMSPlugin implements SubscriberInterface +class MokoSuiteLogistics extends CMSPlugin implements SubscriberInterface { - public static function getSubscribedEvents(): array - { - return [ - 'onBeforeApiRoute' => 'onBeforeApiRoute', - ]; - } + public static function getSubscribedEvents(): array + { + return ['onBeforeApiRoute' => 'onBeforeApiRoute']; + } - public function onBeforeApiRoute(&$router): void - { - $router->createCRUDRoutes('v1/mokosuitelogistics/shipments', 'shipments'); - $router->createCRUDRoutes('v1/mokosuitelogistics/routes', 'routes'); - $router->createCRUDRoutes('v1/mokosuitelogistics/carriers', 'carriers'); - $router->createCRUDRoutes('v1/mokosuitelogistics/warehouses', 'warehouses'); - $router->createCRUDRoutes('v1/mokosuitelogistics/packages', 'packages'); - $router->createCRUDRoutes('v1/mokosuitelogistics/tracking', 'tracking'); - } + public function onBeforeApiRoute(&$event): void + { + $router = $event->getArgument('router'); + $opts = ['component' => 'com_mokosuitelogistics']; + + $router->createCRUDRoutes('v1/mokosuitelogistics/orders', 'orders', $opts); + $router->createCRUDRoutes('v1/mokosuitelogistics/deliveries', 'deliveries', $opts); + $router->createCRUDRoutes('v1/mokosuitelogistics/routes', 'routes', $opts); + $router->createCRUDRoutes('v1/mokosuitelogistics/warehouses', 'warehouses', $opts); + $router->createCRUDRoutes('v1/mokosuitelogistics/pricingrules', 'pricingrules', $opts); + $router->createCRUDRoutes('v1/mokosuitelogistics/drivers', 'drivers', $opts); + $router->createCRUDRoutes('v1/mokosuitelogistics/proofs', 'proofs', $opts); + } } diff --git a/source/pkg_mokosuitelogistics.xml b/source/pkg_mokosuitelogistics.xml index 4b9c3a2..61a56e9 100644 --- a/source/pkg_mokosuitelogistics.xml +++ b/source/pkg_mokosuitelogistics.xml @@ -1,21 +1,24 @@ - MokoSuiteLogistics + Package - MokoSuite Logistics mokosuitelogistics - 0.0.0 - 2026-06 + 06.00.00 + 2026-06-27 Moko Consulting hello@mokoconsulting.tech https://mokoconsulting.tech - (C) 2026 Moko Consulting - GPL-3.0-or-later - Layer 2 — Fleet logistics, shipment tracking, route planning, warehouse management - - plg_system_mokosuitelogistics.zip - com_mokosuitelogistics.zip - plg_webservices_mokosuitelogistics.zip + Copyright (C) 2026 Moko Consulting. All rights reserved. + GNU General Public License version 3 or later; see LICENSE + Delivery management, route optimization, courier dispatch, proof of delivery + 8.3 + + true + + plg_system_mokosuitelogistics.zip + com_mokosuitelogistics.zip + plg_webservices_mokosuitelogistics.zip - https://git.mokoconsulting.tech/api/packages/MokoConsulting/generic/updates/mokosuitelogistics/updates.xml + https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteLogistics/updates.xml