feat: initial scaffold files

This commit is contained in:
2026-06-27 15:27:01 -05:00
parent 6dc85ee82c
commit e2beeb92ac
33 changed files with 483 additions and 204 deletions
+5 -6
View File
@@ -1,9 +1,8 @@
*.min.css
*.min.js
node_modules/
.claude/
.mcp.json
TODO.md
*.min.css
*.min.js
vendor/
node_modules/
.DS_Store
Thumbs.db
*.zip
*.tar.gz
+8 -6
View File
@@ -1,6 +1,8 @@
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later
-->
<!--
INGROUP: MokoSuiteResto.Documentation
BRIEF: Version history using Keep a Changelog
-->
@@ -11,9 +13,9 @@
### Added
- **Repository** -- initial repo creation with scaffolding
- **System Plugin** -- Extension class, service provider, SQL schema
- **SQL Schema** -- 10 tables: menus, menu_items, modifiers, tables, reservations, orders, order_items, inventory, inventory_transactions, staff_shifts
- **Admin Component** -- 8 views: dashboard, menus, items, tables, reservations, orders, inventory, shifts
- **Webservices Plugin** -- 6 API routes: menus, items, tables, reservations, orders, inventory
- **Configuration** -- settings for restaurant basics, orders, reservations, display
- **Access Control** -- granular permissions for menu, reservation, order, inventory, shift management
- **System Plugin** -- Extension class, service provider
- **SQL Schema** -- 8 tables: menus, menu_items, tables, reservations, orders, order_items, inventory, inventory_transactions
- **Admin Component** -- 7 views: dashboard, menus, menu items, tables, reservations, orders, inventory
- **Webservices Plugin** -- 7 API routes: menus, menuitems, tables, reservations, orders, inventory, inventory-transactions
- **Configuration** -- settings across basic, ordering, reservations, kitchen
- **Access Control** -- permissions for granular role-based access
+2 -2
View File
@@ -1,6 +1,6 @@
# MokoSuiteResto
Restaurant operations: menu, reservations, and order management for Joomla 6.
Menu management, table reservations, online ordering, kitchen display, and inventory for Joomla 6.
## Quick Reference
@@ -14,7 +14,7 @@ Restaurant operations: menu, reservations, and order management for Joomla 6.
## Architecture
Joomla **package** -- Layer 2 add-on. CRM contacts as customers, menu management with modifiers, table reservations, order tracking.
Joomla **package** -- Layer 2 add-on. CRM contacts as customers, menu management with categories, table reservations, online ordering with kitchen display, and inventory tracking.
## Rules
+33 -5
View File
@@ -1,15 +1,43 @@
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later
Authored-by: Moko Consulting
-->
# MokoSuiteResto
# MokoSuite Resto
Restaurant operations: menu, reservations, and order management.
Menu management, table reservations, online ordering, kitchen display, and inventory module for MokoSuite on Joomla 6.
Part of the [MokoSuite](https://mokoconsulting.tech) platform — Layer 2 vertical.
## Overview
MokoSuiteResto is a Layer 2 module in the MokoSuite platform, building on MokoSuiteClient (Layer 0) and MokoSuiteCRM (Layer 1) to provide complete restaurant operations management.
## Features
- **Menu Management** -- menus with categories, items, pricing, allergens, dietary tags
- **Table Management** -- sections, capacity tracking, real-time status
- **Reservations** -- party size, time slots, auto-confirm, special requests
- **Online Ordering** -- dine-in, takeout, delivery, and catering order types
- **Kitchen Display** -- order status tracking from pending to served
- **Inventory** -- stock tracking with minimum levels, supplier info, expiry dates
- **Inventory Transactions** -- received, used, wasted, adjusted, returned tracking
## Requirements
- Joomla 6.x
- PHP 8.3+
- MokoSuiteClient (Layer 0)
- MokoSuiteCRM (Layer 1)
## Installation
Install via Joomla Extension Manager using the package file `pkg_mokosuiteresto.zip`.
## License
GNU General Public License v3.0 or later. See [LICENSE](LICENSE).
GNU General Public License v3.0 or later -- see [LICENSE](LICENSE).
## Links
- [Documentation](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteResto/wiki)
- [Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteResto/issues)
- [MokoSuite Platform](https://mokoconsulting.tech)
@@ -1,11 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<access component="com_mokosuiteresto">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.manage" title="JACTION_MANAGE" />
<action name="core.create" title="JACTION_CREATE" />
<action name="core.delete" title="JACTION_DELETE" />
<action name="core.edit" title="JACTION_EDIT" />
<action name="core.edit.state" title="JACTION_EDITSTATE" />
</section>
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.options" title="JACTION_OPTIONS" />
<action name="core.manage" title="JACTION_MANAGE" />
<action name="core.create" title="JACTION_CREATE" />
<action name="core.delete" title="JACTION_DELETE" />
<action name="core.edit" title="JACTION_EDIT" />
<action name="resto.menus.manage" title="Manage Menus" />
<action name="resto.tables.manage" title="Manage Tables" />
<action name="resto.reservations.manage" title="Manage Reservations" />
<action name="resto.reservations.confirm" title="Confirm Reservations" />
<action name="resto.orders.manage" title="Manage Orders" />
<action name="resto.orders.cancel" title="Cancel Orders" />
<action name="resto.orders.complete" title="Complete Orders" />
<action name="resto.kitchen.view" title="View Kitchen Display" />
<action name="resto.inventory.manage" title="Manage Inventory" />
<action name="resto.reports" title="View Reports" />
<action name="resto.settings" title="Manage Settings" />
</section>
</access>
@@ -1,6 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<config>
<fieldset name="component" label="COM_MOKOSUITERESTO_CONFIG">
<field name="items_per_page" type="number" default="20" label="Items Per Page" min="5" max="100" />
</fieldset>
<fieldset name="basic" label="Restaurant Defaults">
<field name="restaurant_name" type="text" default="" label="Restaurant Name" />
<field name="default_currency" type="text" default="USD" label="Default Currency" />
<field name="timezone" type="text" default="UTC" label="Operating Timezone" />
<field name="tax_rate" type="number" default="0" step="0.01" label="Tax Rate (%)" />
</fieldset>
<fieldset name="ordering" label="Ordering">
<field name="enable_online_ordering" type="radio" default="1" label="Enable Online Ordering" class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="minimum_order_amount" type="number" default="0" step="0.01" label="Minimum Order Amount" />
<field name="prep_time_minutes" type="number" default="30" label="Default Prep Time (min)" />
</fieldset>
<fieldset name="reservations" label="Reservations">
<field name="max_party_size" type="number" default="20" label="Max Party Size" />
<field name="time_slot_minutes" type="number" default="30" label="Time Slot (min)" />
<field name="auto_confirm" type="radio" default="0" label="Auto-Confirm Reservations" class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</fieldset>
<fieldset name="kitchen" label="Kitchen">
<field name="display_refresh_seconds" type="number" default="30" label="Display Refresh (seconds)" />
</fieldset>
</config>
@@ -1,30 +1,26 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* 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\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));
return $c;
});
}
};
@@ -1,10 +1,12 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace MokoConsulting\Component\MokoSuiteResto\Administrator\Controller;
namespace Moko\Component\MokoSuiteResto\Administrator\Controller;
defined('_JEXEC') or die;
@@ -12,5 +14,5 @@ use Joomla\CMS\MVC\Controller\BaseController;
class DisplayController extends BaseController
{
protected $default_view = 'restodashboard';
protected $default_view = 'restodashboard';
}
@@ -1,10 +1,12 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace MokoConsulting\Component\MokoSuiteResto\Administrator\Model;
namespace Moko\Component\MokoSuiteResto\Administrator\Model;
defined('_JEXEC') or die;
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteResto\Administrator\View\Inventory;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Inventory');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteResto\Administrator\View\MenuItems;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Menu Items');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteResto\Administrator\View\Menus;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Menus');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteResto\Administrator\View\Orders;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Orders');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteResto\Administrator\View\Reservations;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Reservations');
parent::display($tpl);
}
}
@@ -1,10 +1,12 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace MokoConsulting\Component\MokoSuiteResto\Administrator\View\RestoDashboard;
namespace Moko\Component\MokoSuiteResto\Administrator\View\RestoDashboard;
defined('_JEXEC') or die;
@@ -13,9 +15,9 @@ use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('Dashboard', 'generic');
parent::display($tpl);
}
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Dashboard');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteResto\Administrator\View\Tables;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null): void
{
ToolbarHelper::title('MokoSuite Resto - Tables');
parent::display($tpl);
}
}
@@ -0,0 +1 @@
<?php defined('_JEXEC') or die; ?><div><h2>Inventory</h2><p>Coming soon.</p></div>
@@ -0,0 +1 @@
<?php defined('_JEXEC') or die; ?><div><h2>Menu Items</h2><p>Coming soon.</p></div>
@@ -0,0 +1 @@
<?php defined('_JEXEC') or die; ?><div><h2>Menus</h2><p>Coming soon.</p></div>
@@ -0,0 +1 @@
<?php defined('_JEXEC') or die; ?><div><h2>Orders</h2><p>Coming soon.</p></div>
@@ -0,0 +1 @@
<?php defined('_JEXEC') or die; ?><div><h2>Reservations</h2><p>Coming soon.</p></div>
@@ -1,15 +1 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="row">
<div class="col-12">
<h2>Dashboard</h2>
<p>Manage dashboard here.</p>
</div>
</div>
<?php defined('_JEXEC') or die; ?><div><h2>Dashboard</h2><p>Coming soon.</p></div>
@@ -0,0 +1 @@
<?php defined('_JEXEC') or die; ?><div><h2>Tables</h2><p>Coming soon.</p></div>
@@ -1,33 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" method="upgrade">
<name>com_mokosuiteresto</name>
<version>0.0.0</version>
<creationDate>2026-06</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<copyright>(C) 2026 Moko Consulting</copyright>
<license>GPL-3.0-or-later</license>
<description>Layer 2 — Restaurant management, menus, tables, reservations, orders, and inventory</description>
<namespace path="src">MokoConsulting\Component\MokoSuiteResto</namespace>
<administration>
<files folder="admin">
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
<folder>language</folder>
<filename>access.xml</filename>
<filename>config.xml</filename>
</files>
<menu>MokoSuiteResto</menu>
<submenu>
<menu link="option=com_mokosuiteresto&amp;view=restodashboard">Dashboard</menu>
<menu link="option=com_mokosuiteresto&amp;view=restomenus">Menus</menu>
<menu link="option=com_mokosuiteresto&amp;view=restomenuitems">Menu Items</menu>
<menu link="option=com_mokosuiteresto&amp;view=restotables">Tables</menu>
<menu link="option=com_mokosuiteresto&amp;view=restoreservations">Reservations</menu>
<menu link="option=com_mokosuiteresto&amp;view=restoorders">Orders</menu>
<menu link="option=com_mokosuiteresto&amp;view=restoinventory">Inventory</menu>
</submenu>
</administration>
<name>MokoSuite Resto</name>
<author>Moko Consulting</author>
<creationDate>2026-06-27</creationDate>
<copyright>Copyright (C) 2026 Moko Consulting.</copyright>
<license>GPL-3.0-or-later</license>
<version>06.00.00</version>
<namespace path="src">Moko\Component\MokoSuiteResto</namespace>
<administration>
<files folder="admin"><folder>services</folder><folder>src</folder><folder>tmpl</folder></files>
<menu>COM_MOKOSUITERESTO</menu>
</administration>
</extension>
@@ -1,2 +1,2 @@
PLG_SYSTEM_MOKOSUITERESTO="System - MokoSuite Resto"
PLG_SYSTEM_MOKOSUITERESTO_DESC="Restaurant operations: menu, reservations, and order management"
PLG_SYSTEM_MOKOSUITERESTO_DESC="Menu management, table reservations, online ordering, kitchen display, and inventory"
@@ -1,2 +1,2 @@
PLG_SYSTEM_MOKOSUITERESTO="System - MokoSuite Resto"
PLG_SYSTEM_MOKOSUITERESTO_DESC="Restaurant operations: menu, reservations, and order management"
PLG_SYSTEM_MOKOSUITERESTO_DESC="Menu management, table reservations, online ordering, kitchen display, and inventory"
@@ -26,32 +26,30 @@
<uninstall><sql><file driver="mysql" charset="utf8">sql/uninstall.mysql.sql</file></sql></uninstall>
<config>
<fields name="params">
<fieldset name="basic" label="Restaurant Basics">
<fieldset name="basic" label="Restaurant Defaults">
<field name="restaurant_name" type="text" default="" label="Restaurant Name" />
<field name="default_currency" type="text" default="USD" label="Default Currency" />
<field name="timezone" type="text" default="UTC" label="Operating Timezone" />
<field name="currency" type="text" default="USD" label="Currency" />
<field name="tax_rate" type="number" default="0" step="0.01" label="Tax Rate (%)" />
</fieldset>
<fieldset name="orders" label="Orders">
<field name="auto_accept_orders" type="radio" default="0" label="Auto-Accept Orders" class="btn-group btn-group-yesno">
<fieldset name="ordering" label="Ordering">
<field name="enable_online_ordering" type="radio" default="1" label="Enable Online Ordering" class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="prep_time_buffer" type="number" default="15" label="Prep Time Buffer (min)" />
<field name="minimum_order_amount" type="number" default="0" step="0.01" label="Minimum Order Amount" />
<field name="prep_time_minutes" type="number" default="30" label="Default Prep Time (min)" />
</fieldset>
<fieldset name="reservations" label="Reservations">
<field name="max_party_size" type="number" default="20" label="Max Party Size" />
<field name="default_duration" type="number" default="90" label="Default Duration (min)" />
<field name="advance_booking_days" type="number" default="30" label="Advance Booking (days)" />
<field name="time_slot_minutes" type="number" default="30" label="Time Slot (min)" />
<field name="auto_confirm" type="radio" default="0" label="Auto-Confirm Reservations" class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</fieldset>
<fieldset name="display" label="Display">
<field name="show_prices" type="radio" default="1" label="Show Prices" class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="show_calories" type="radio" default="0" label="Show Calories" class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<fieldset name="kitchen" label="Kitchen">
<field name="display_refresh_seconds" type="number" default="30" label="Display Refresh (seconds)" />
</fieldset>
</fields>
</config>
@@ -1,23 +1,149 @@
-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Authored-by: Moko Consulting
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_menus` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`description` TEXT,
`menu_type` ENUM('breakfast','lunch','dinner','brunch','drinks','dessert','kids','catering','special') NOT NULL DEFAULT 'dinner',
`available_start` TIME DEFAULT NULL,
`available_end` TIME DEFAULT NULL,
`photo` VARCHAR(500) NOT NULL DEFAULT '',
`published` TINYINT NOT NULL DEFAULT 1,
`ordering` INT NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_type` (`menu_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_menus` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `description` TEXT, `menu_type` ENUM('breakfast','lunch','dinner','brunch','drinks','desserts','specials','kids') NOT NULL DEFAULT 'dinner', `available_from` TIME DEFAULT NULL, `available_to` TIME DEFAULT NULL, `published` TINYINT NOT NULL DEFAULT 1, `ordering` INT NOT NULL DEFAULT 0, `created` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_menu_items` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`menu_id` INT UNSIGNED NOT NULL,
`name` VARCHAR(255) NOT NULL,
`description` TEXT,
`category` VARCHAR(100) NOT NULL DEFAULT '',
`price` DECIMAL(10,2) NOT NULL,
`calories` SMALLINT UNSIGNED DEFAULT NULL,
`allergens` JSON DEFAULT NULL,
`dietary_tags` JSON DEFAULT NULL,
`available` TINYINT NOT NULL DEFAULT 1,
`featured` TINYINT NOT NULL DEFAULT 0,
`photo` VARCHAR(500) NOT NULL DEFAULT '',
`published` TINYINT NOT NULL DEFAULT 1,
`ordering` INT NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_menu` (`menu_id`),
KEY `idx_category` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_menu_items` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `menu_id` INT UNSIGNED NOT NULL, `name` VARCHAR(255) NOT NULL, `description` TEXT, `category` VARCHAR(100) NOT NULL DEFAULT '', `price` DECIMAL(10,2) NOT NULL, `calories` SMALLINT UNSIGNED DEFAULT NULL, `allergens` VARCHAR(500) NOT NULL DEFAULT '', `dietary_tags` VARCHAR(255) NOT NULL DEFAULT '', `prep_time_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 15, `photo` VARCHAR(500) NOT NULL DEFAULT '', `available` TINYINT NOT NULL DEFAULT 1, `published` TINYINT NOT NULL DEFAULT 1, `ordering` INT NOT NULL DEFAULT 0, `created` DATETIME NOT NULL, PRIMARY KEY (`id`), KEY `idx_menu` (`menu_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_tables` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`table_number` VARCHAR(20) NOT NULL,
`section` VARCHAR(50) NOT NULL DEFAULT '',
`capacity` TINYINT UNSIGNED NOT NULL DEFAULT 4,
`table_type` ENUM('indoor','outdoor','patio','bar','private','booth') NOT NULL DEFAULT 'indoor',
`status` ENUM('available','occupied','reserved','cleaning','closed') NOT NULL DEFAULT 'available',
`published` TINYINT NOT NULL DEFAULT 1,
`ordering` INT NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_number` (`table_number`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_modifiers` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `menu_item_id` INT UNSIGNED NOT NULL, `name` VARCHAR(255) NOT NULL, `modifier_type` ENUM('add_on','size','preparation','sauce','side','substitution') NOT NULL DEFAULT 'add_on', `price_adjustment` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `ordering` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_item` (`menu_item_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_reservations` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`reservation_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 '',
`table_id` INT UNSIGNED DEFAULT NULL,
`party_size` TINYINT UNSIGNED NOT NULL DEFAULT 2,
`reservation_date` DATE NOT NULL,
`reservation_time` TIME NOT NULL,
`duration_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 90,
`status` ENUM('pending','confirmed','seated','completed','cancelled','no_show') NOT NULL DEFAULT 'pending',
`special_requests` TEXT,
`created` DATETIME NOT NULL,
`created_by` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_ref` (`reservation_ref`),
KEY `idx_customer` (`customer_contact_id`),
KEY `idx_table` (`table_id`),
KEY `idx_date` (`reservation_date`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_tables` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `table_number` VARCHAR(20) NOT NULL, `section` VARCHAR(100) NOT NULL DEFAULT '', `capacity` TINYINT UNSIGNED NOT NULL DEFAULT 4, `table_type` ENUM('indoor','outdoor','patio','bar','private','booth') NOT NULL DEFAULT 'indoor', `status` ENUM('available','occupied','reserved','cleaning','closed') NOT NULL DEFAULT 'available', `published` TINYINT NOT NULL DEFAULT 1, `ordering` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_status` (`status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_orders` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`order_ref` VARCHAR(20) NOT NULL,
`table_id` INT UNSIGNED DEFAULT NULL,
`customer_contact_id` INT DEFAULT NULL,
`customer_name` VARCHAR(255) NOT NULL DEFAULT '',
`order_type` ENUM('dine_in','takeout','delivery','catering') NOT NULL DEFAULT 'dine_in',
`status` ENUM('pending','confirmed','preparing','ready','served','completed','cancelled') NOT NULL DEFAULT 'pending',
`subtotal` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`tax` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`tip` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`discount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`total` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`payment_method` ENUM('cash','card','online','gift_card','split') NOT NULL DEFAULT 'card',
`payment_status` ENUM('pending','paid','refunded','voided') NOT NULL DEFAULT 'pending',
`notes` TEXT,
`ordered_at` DATETIME NOT NULL,
`completed_at` DATETIME DEFAULT NULL,
`created` DATETIME NOT NULL,
`created_by` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_ref` (`order_ref`),
KEY `idx_table` (`table_id`),
KEY `idx_status` (`status`),
KEY `idx_type` (`order_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_reservations` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `reservation_ref` VARCHAR(20) NOT NULL, `customer_contact_id` INT DEFAULT NULL, `customer_name` VARCHAR(255) NOT NULL, `customer_phone` VARCHAR(50) NOT NULL DEFAULT '', `table_id` INT UNSIGNED DEFAULT NULL, `party_size` TINYINT UNSIGNED NOT NULL DEFAULT 2, `reservation_date` DATE NOT NULL, `reservation_time` TIME NOT NULL, `duration_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 90, `status` ENUM('pending','confirmed','seated','completed','cancelled','no_show') NOT NULL DEFAULT 'pending', `special_requests` TEXT, `created` DATETIME NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_ref` (`reservation_ref`), KEY `idx_customer` (`customer_contact_id`), KEY `idx_date` (`reservation_date`), KEY `idx_status` (`status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_order_items` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`order_id` INT UNSIGNED NOT NULL,
`menu_item_id` INT UNSIGNED NOT NULL,
`quantity` TINYINT UNSIGNED NOT NULL DEFAULT 1,
`unit_price` DECIMAL(10,2) NOT NULL,
`modifiers_json` JSON DEFAULT NULL,
`modifiers_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`line_total` DECIMAL(10,2) NOT NULL,
`status` ENUM('pending','preparing','ready','served','cancelled') NOT NULL DEFAULT 'pending',
`special_instructions` TEXT,
PRIMARY KEY (`id`),
KEY `idx_order` (`order_id`),
KEY `idx_item` (`menu_item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_orders` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `order_ref` VARCHAR(20) NOT NULL, `order_type` ENUM('dine_in','takeout','delivery','catering') NOT NULL DEFAULT 'dine_in', `table_id` INT UNSIGNED DEFAULT NULL, `customer_name` VARCHAR(255) NOT NULL DEFAULT '', `status` ENUM('pending','preparing','ready','served','completed','cancelled') NOT NULL DEFAULT 'pending', `subtotal` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `tax` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `tip` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `total` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `payment_method` ENUM('cash','card','tab','comp') NOT NULL DEFAULT 'card', `payment_status` ENUM('pending','paid','refunded') NOT NULL DEFAULT 'pending', `server_name` VARCHAR(255) NOT NULL DEFAULT '', `notes` TEXT, `created` DATETIME NOT NULL, `created_by` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `idx_ref` (`order_ref`), KEY `idx_table` (`table_id`), KEY `idx_status` (`status`), KEY `idx_created` (`created`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_inventory` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`category` VARCHAR(100) NOT NULL DEFAULT '',
`unit` ENUM('ea','oz','lb','kg','gal','ltr','case','box','bag','other') NOT NULL DEFAULT 'ea',
`current_stock` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`minimum_stock` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`cost_per_unit` DECIMAL(10,4) NOT NULL DEFAULT 0.0000,
`supplier` VARCHAR(255) NOT NULL DEFAULT '',
`expiry_date` DATE DEFAULT NULL,
`notes` TEXT,
`published` TINYINT NOT NULL DEFAULT 1,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_category` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_order_items` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `order_id` INT UNSIGNED NOT NULL, `menu_item_id` INT UNSIGNED NOT NULL, `quantity` SMALLINT UNSIGNED NOT NULL DEFAULT 1, `unit_price` DECIMAL(10,2) NOT NULL, `modifiers` JSON DEFAULT NULL, `modifiers_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `special_instructions` VARCHAR(500) NOT NULL DEFAULT '', `status` ENUM('pending','preparing','ready','served','cancelled') NOT NULL DEFAULT 'pending', PRIMARY KEY (`id`), KEY `idx_order` (`order_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_inventory` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `category` ENUM('produce','meat','seafood','dairy','dry_goods','beverages','supplies','other') NOT NULL DEFAULT 'other', `unit` VARCHAR(50) NOT NULL DEFAULT 'each', `current_qty` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `reorder_level` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `unit_cost` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `supplier` VARCHAR(255) NOT NULL DEFAULT '', `created` DATETIME NOT NULL, PRIMARY KEY (`id`), KEY `idx_category` (`category`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_inventory_transactions` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `inventory_id` INT UNSIGNED NOT NULL, `transaction_type` ENUM('received','used','waste','adjustment','transfer') NOT NULL DEFAULT 'received', `quantity` DECIMAL(10,2) NOT NULL, `unit_cost` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `reference` VARCHAR(255) NOT NULL DEFAULT '', `created` DATETIME NOT NULL, `created_by` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_inventory` (`inventory_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_staff_shifts` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `staff_name` VARCHAR(255) NOT NULL, `contact_id` INT DEFAULT NULL, `role` ENUM('server','bartender','host','cook','chef','dishwasher','manager','busser') NOT NULL DEFAULT 'server', `shift_date` DATE NOT NULL, `start_time` TIME NOT NULL, `end_time` TIME NOT NULL, `status` ENUM('scheduled','active','completed','no_show','cancelled') NOT NULL DEFAULT 'scheduled', `tips_earned` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `created` DATETIME NOT NULL, PRIMARY KEY (`id`), KEY `idx_date` (`shift_date`), KEY `idx_role` (`role`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuiteresto_inventory_transactions` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`inventory_id` INT UNSIGNED NOT NULL,
`transaction_type` ENUM('received','used','wasted','adjusted','returned') NOT NULL,
`quantity` DECIMAL(10,2) NOT NULL,
`cost` DECIMAL(10,2) DEFAULT NULL,
`reference` VARCHAR(255) NOT NULL DEFAULT '',
`notes` TEXT,
`created` DATETIME NOT NULL,
`created_by` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_inventory` (`inventory_id`),
KEY `idx_type` (`transaction_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
@@ -1,14 +1,8 @@
-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Authored-by: Moko Consulting
DROP TABLE IF EXISTS `#__mokosuiteresto_staff_shifts`;
DROP TABLE IF EXISTS `#__mokosuiteresto_inventory_transactions`;
DROP TABLE IF EXISTS `#__mokosuiteresto_inventory`;
DROP TABLE IF EXISTS `#__mokosuiteresto_order_items`;
DROP TABLE IF EXISTS `#__mokosuiteresto_orders`;
DROP TABLE IF EXISTS `#__mokosuiteresto_reservations`;
DROP TABLE IF EXISTS `#__mokosuiteresto_tables`;
DROP TABLE IF EXISTS `#__mokosuiteresto_modifiers`;
DROP TABLE IF EXISTS `#__mokosuiteresto_menu_items`;
DROP TABLE IF EXISTS `#__mokosuiteresto_menus`;
@@ -1,17 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0"?>
<extension type="plugin" group="webservices" method="upgrade">
<name>plg_webservices_mokosuiteresto</name>
<version>0.0.0</version>
<creationDate>2026-06</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<copyright>(C) 2026 Moko Consulting</copyright>
<license>GPL-3.0-or-later</license>
<description>MokoSuiteResto webservices plugin</description>
<namespace path="src">MokoConsulting\Plugin\WebServices\MokoSuiteResto</namespace>
<files>
<folder>src</folder>
<folder>services</folder>
</files>
<name>Web Services - MokoSuite Resto</name>
<element>mokosuiteresto</element>
<author>Moko Consulting</author>
<version>06.00.00</version>
<license>GPL-3.0-or-later</license>
<namespace path="src">Moko\Plugin\WebServices\MokoSuiteResto</namespace>
<files><folder>src</folder><folder>services</folder></files>
</extension>
@@ -1,31 +1,24 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* 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\MokoSuiteResto\Extension\MokoSuiteResto;
use Moko\Plugin\WebServices\MokoSuiteResto\Extension\MokoSuiteResto;
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 MokoSuiteResto($dispatcher, (array) PluginHelper::getPlugin('webservices', 'mokosuiteresto'));
$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 MokoSuiteResto($container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('webservices', 'mokosuiteresto'));
});
}
};
@@ -1,34 +1,36 @@
<?php
/**
* @copyright (C) 2026 Moko Consulting
* @license GPL-3.0-or-later
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace MokoConsulting\Plugin\WebServices\MokoSuiteResto\Extension;
namespace Moko\Plugin\WebServices\MokoSuiteResto\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 MokoSuiteResto extends CMSPlugin implements SubscriberInterface
class MokoSuiteResto 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/mokosuiteresto/menus', 'menus');
$router->createCRUDRoutes('v1/mokosuiteresto/menu-items', 'menuitems');
$router->createCRUDRoutes('v1/mokosuiteresto/tables', 'tables');
$router->createCRUDRoutes('v1/mokosuiteresto/reservations', 'reservations');
$router->createCRUDRoutes('v1/mokosuiteresto/orders', 'orders');
$router->createCRUDRoutes('v1/mokosuiteresto/inventory', 'inventory');
}
public function onBeforeApiRoute(&$event): void
{
$router = $event->getArgument('router');
$opts = ['component' => 'com_mokosuiteresto'];
$router->createCRUDRoutes('v1/mokosuiteresto/menus', 'menus', $opts);
$router->createCRUDRoutes('v1/mokosuiteresto/menuitems', 'menuitems', $opts);
$router->createCRUDRoutes('v1/mokosuiteresto/tables', 'tables', $opts);
$router->createCRUDRoutes('v1/mokosuiteresto/reservations', 'reservations', $opts);
$router->createCRUDRoutes('v1/mokosuiteresto/orders', 'orders', $opts);
$router->createCRUDRoutes('v1/mokosuiteresto/inventory', 'inventory', $opts);
$router->createCRUDRoutes('v1/mokosuiteresto/inventory-transactions', 'inventorytransactions', $opts);
}
}
+1 -3
View File
@@ -9,14 +9,12 @@
<authorUrl>https://mokoconsulting.tech</authorUrl>
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
<license>GNU General Public License version 3 or later; see LICENSE</license>
<description>Restaurant operations: menu, reservations, and order management</description>
<description>Menu management, table reservations, online ordering, kitchen display, and inventory</description>
<php_minimum>8.3</php_minimum>
<dlid prefix="dlid=" suffix=""/>
<blockChildUninstall>true</blockChildUninstall>
<files folder="packages">
<file type="plugin" id="plg_system_mokosuiteresto" group="system">plg_system_mokosuiteresto.zip</file>
<file type="component" id="com_mokosuiteresto">com_mokosuiteresto.zip</file>
<file type="plugin" id="plg_webservices_mokosuiteresto" group="webservices">plg_webservices_mokosuiteresto.zip</file>
</files>
<updateservers>
<server type="extension" priority="1" name="Package - MokoSuite Resto">https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteResto/updates.xml</server>