feat: complete scaffold with system plugin, component, and webservices plugin
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
.claude/
|
||||
.mcp.json
|
||||
TODO.md
|
||||
*.min.css
|
||||
*.min.js
|
||||
vendor/
|
||||
node_modules/
|
||||
@@ -0,0 +1,19 @@
|
||||
<!--
|
||||
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
INGROUP: MokoSuitebooking.Documentation
|
||||
BRIEF: Version history using Keep a Changelog
|
||||
-->
|
||||
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- **Repository** -- initial scaffold
|
||||
- **System Plugin** -- Extension class, service provider
|
||||
- **SQL Schema** -- 8 tables: locations, services, staff, schedules, availability_overrides, bookings, booking_services, waitlist
|
||||
- **Admin Component** -- 6 views: dashboard, bookings, services, staff, schedules, locations
|
||||
- **Webservices Plugin** -- 7 API routes
|
||||
- **Configuration** -- plugin settings across 4 fieldsets
|
||||
- **Access Control** -- granular permissions
|
||||
@@ -0,0 +1,30 @@
|
||||
# MokoSuitebooking
|
||||
|
||||
Appointment and resource booking for service businesses for Joomla 6.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Package** | `pkg_mokosuitebooking` |
|
||||
| **Layer** | 2 (requires: Client, CRM) |
|
||||
| **Language** | PHP 8.3+ |
|
||||
| **Branch** | develop on `dev`, merge to `main` (protected) |
|
||||
|
||||
## Architecture
|
||||
|
||||
Joomla **package** -- Layer 2 add-on. CRM contacts as clients, service catalog with staff scheduling and online booking.
|
||||
|
||||
## Rules
|
||||
|
||||
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
|
||||
- **Attribution**: `Authored-by: Moko Consulting`
|
||||
- **Workflow directory**: `.mokogitea/`
|
||||
- **Standards**: [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoCLI/wiki)
|
||||
- **Changelog**: `[Unreleased]` only -- release system assigns versions
|
||||
|
||||
## Coding Standards
|
||||
|
||||
- PHP 8.3+ / Joomla 6 patterns
|
||||
- `$this->getDatabase()` in models, `Factory::getContainer()->get(DatabaseInterface::class)` in helpers
|
||||
- `Factory::getApplication()->getIdentity()` for user
|
||||
@@ -1,3 +1,45 @@
|
||||
# MokoSuiteBooking
|
||||
<!--
|
||||
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
|
||||
MokoSuite Booking — appointment and resource booking for service businesses on Joomla 6
|
||||
# MokoSuite booking
|
||||
|
||||
Appointment and resource booking for service businesses for MokoSuite on Joomla 6.
|
||||
|
||||
## Overview
|
||||
|
||||
MokoSuitebooking is a **Layer 2** extension in the MokoSuite platform, building on MokoSuiteClient (Layer 0) and MokoSuiteCRM (Layer 1).
|
||||
|
||||
## Features
|
||||
|
||||
- **Service Catalog** -- services with duration, pricing, staff assignment
|
||||
- **Online Booking** -- real-time availability with booking widget
|
||||
- **Staff Scheduling** -- recurring availability patterns with overrides
|
||||
- **Multi-Location** -- support for multiple business locations
|
||||
- **Walk-In Queue** -- walk-in queue management
|
||||
- **Client History** -- CRM contact-linked visit frequency and spend tracking
|
||||
- **Waitlist** -- automated notification when slots open
|
||||
- **REST API** -- full CRUD for services, staff, bookings, schedules, locations
|
||||
- **Access Control** -- granular permissions
|
||||
|
||||
## Requirements
|
||||
|
||||
- Joomla 6.x
|
||||
- PHP 8.3+
|
||||
- MokoSuiteClient (Layer 0)
|
||||
- MokoSuiteCRM (Layer 1)
|
||||
|
||||
## Installation
|
||||
|
||||
Install via Joomla Extension Manager using the package file `pkg_mokosuitebooking.zip`.
|
||||
|
||||
## License
|
||||
|
||||
GNU General Public License v3.0 or later.
|
||||
|
||||
## Links
|
||||
|
||||
- [Documentation](https://git.mokoconsulting.tech/MokoConsulting/MokoSuitebooking/wiki)
|
||||
- [Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoSuitebooking/issues)
|
||||
- [MokoSuite Platform](https://mokoconsulting.tech)
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<access component="com_mokosuitebooking">
|
||||
<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="core.edit.state" title="JACTION_EDITSTATE" />
|
||||
<action name="core.edit.own" title="JACTION_EDITOWN" />
|
||||
<action name="booking.manage.services" title="Manage Services" />
|
||||
<action name="booking.manage.staff" title="Manage Staff" />
|
||||
<action name="booking.manage.schedules" title="Manage Schedules" />
|
||||
<action name="booking.view.reports" title="View Reports" />
|
||||
</section>
|
||||
</access>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<config>
|
||||
<fieldset name="permissions" label="JCONFIG_PERMISSIONS_LABEL" description="JCONFIG_PERMISSIONS_DESC">
|
||||
<field name="rules" type="rules" label="JCONFIG_PERMISSIONS_LABEL" validate="rules" filter="rules" component="com_mokosuitebooking" section="component" />
|
||||
</fieldset>
|
||||
</config>
|
||||
@@ -0,0 +1,9 @@
|
||||
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
COM_MOKOSUITEBOOKING="MokoSuite Booking"
|
||||
COM_MOKOSUITEBOOKING_DASHBOARD="Dashboard"
|
||||
COM_MOKOSUITEBOOKING_BOOKINGS="Bookings"
|
||||
COM_MOKOSUITEBOOKING_SERVICES="Services"
|
||||
COM_MOKOSUITEBOOKING_STAFF="Staff"
|
||||
COM_MOKOSUITEBOOKING_SCHEDULES="Schedules"
|
||||
COM_MOKOSUITEBOOKING_LOCATIONS="Locations"
|
||||
@@ -0,0 +1,4 @@
|
||||
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
COM_MOKOSUITEBOOKING="MokoSuite Booking"
|
||||
COM_MOKOSUITEBOOKING_XML_DESCRIPTION="Appointment and resource booking"
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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\ComponentInterface;
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
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) {
|
||||
$c = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class));
|
||||
$c->setMVCFactory($container->get(MVCFactoryInterface::class));
|
||||
$c->setRouterFactory($container->get(RouterFactoryInterface::class));
|
||||
return $c;
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\Administrator\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
protected $default_view = 'bookingdashboard';
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
|
||||
class BookingDashboardModel extends BaseDatabaseModel
|
||||
{
|
||||
}
|
||||
@@ -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\MokoSuiteBooking\Administrator\View\BookingBookings;
|
||||
|
||||
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 Booking - Bookings');
|
||||
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\MokoSuiteBooking\Administrator\View\BookingDashboard;
|
||||
|
||||
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 Booking - 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\MokoSuiteBooking\Administrator\View\BookingLocations;
|
||||
|
||||
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 Booking - Locations');
|
||||
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\MokoSuiteBooking\Administrator\View\BookingSchedules;
|
||||
|
||||
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 Booking - Schedules');
|
||||
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\MokoSuiteBooking\Administrator\View\BookingServices;
|
||||
|
||||
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 Booking - Services');
|
||||
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\MokoSuiteBooking\Administrator\View\BookingStaff;
|
||||
|
||||
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 Booking - Staff');
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
defined('_JEXEC') or die;
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Bookings</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
defined('_JEXEC') or die;
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Dashboard</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
defined('_JEXEC') or die;
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Locations</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
defined('_JEXEC') or die;
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Schedules</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
defined('_JEXEC') or die;
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Services</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
defined('_JEXEC') or die;
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Staff</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="component" method="upgrade">
|
||||
<name>MokoSuite Booking</name>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting.</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<version>06.00.00</version>
|
||||
<description>Appointment and resource booking</description>
|
||||
<namespace path="src">Moko\Component\MokoSuiteBooking</namespace>
|
||||
<administration>
|
||||
<files folder="admin">
|
||||
<filename>access.xml</filename>
|
||||
<filename>config.xml</filename>
|
||||
<folder>language</folder>
|
||||
<folder>services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages folder="admin/language">
|
||||
<language tag="en-GB">en-GB/com_mokosuitebooking.ini</language>
|
||||
<language tag="en-GB">en-GB/com_mokosuitebooking.sys.ini</language>
|
||||
</languages>
|
||||
<menu>COM_MOKOSUITEBOOKING</menu>
|
||||
<submenu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookingdashboard">COM_MOKOSUITEBOOKING_DASHBOARD</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookingbookings">COM_MOKOSUITEBOOKING_BOOKINGS</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookingservices">COM_MOKOSUITEBOOKING_SERVICES</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookingstaff">COM_MOKOSUITEBOOKING_STAFF</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookingschedules">COM_MOKOSUITEBOOKING_SCHEDULES</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookinglocations">COM_MOKOSUITEBOOKING_LOCATIONS</menu>
|
||||
</submenu>
|
||||
</administration>
|
||||
</extension>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING="System - MokoSuite Booking"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_DESC="Appointment booking helpers and schema"
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING="System - MokoSuite Booking"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_DESC="Appointment booking helpers and schema"
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="plugin" group="system" method="upgrade">
|
||||
<name>System - MokoSuite Booking</name>
|
||||
<element>mokosuitebooking</element>
|
||||
<author>Moko Consulting</author>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<version>06.00.00</version>
|
||||
<php_minimum>8.3</php_minimum>
|
||||
<description>PLG_SYSTEM_MOKOSUITEBOOKING_DESC</description>
|
||||
<namespace path="src">Moko\Plugin\System\MokoSuiteBooking</namespace>
|
||||
<files>
|
||||
<folder>src</folder>
|
||||
<folder>services</folder>
|
||||
<folder>language</folder>
|
||||
<folder>sql</folder>
|
||||
</files>
|
||||
<languages folder="language">
|
||||
<language tag="en-GB">en-GB/plg_system_mokosuitebooking.ini</language>
|
||||
<language tag="en-GB">en-GB/plg_system_mokosuitebooking.sys.ini</language>
|
||||
</languages>
|
||||
<install><sql><file driver="mysql" charset="utf8">sql/install.mysql.sql</file></sql></install>
|
||||
<uninstall><sql><file driver="mysql" charset="utf8">sql/uninstall.mysql.sql</file></sql></uninstall>
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic" label="Booking Defaults">
|
||||
<field name="timezone" type="timezone" default="America/New_York" label="Default Timezone" />
|
||||
<field name="slot_duration" type="number" default="30" label="Default Slot Duration (min)" />
|
||||
<field name="default_currency" type="text" default="USD" label="Default Currency" />
|
||||
</fieldset>
|
||||
<fieldset name="booking" label="Booking Rules">
|
||||
<field name="advance_booking_days" type="number" default="30" label="Max Advance Booking (days)" />
|
||||
<field name="cancellation_window_hours" type="number" default="24" label="Cancellation Window (hours)" />
|
||||
<field name="auto_confirm" type="radio" default="1" label="Auto-Confirm Bookings" class="btn-group btn-group-yesno">
|
||||
<option value="1">JYES</option>
|
||||
<option value="0">JNO</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="notifications" label="Notifications">
|
||||
<field name="reminder_hours" type="number" default="24" label="Reminder Before (hours)" />
|
||||
<field name="no_show_policy" type="list" default="none" label="No-Show Policy">
|
||||
<option value="none">None</option>
|
||||
<option value="flag">Flag Only</option>
|
||||
<option value="fee">Apply Fee</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="display" label="Display">
|
||||
<field name="calendar_default_view" type="list" default="week" label="Default Calendar View">
|
||||
<option value="day">Day</option>
|
||||
<option value="week">Week</option>
|
||||
<option value="month">Month</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Moko\Plugin\System\MokoSuiteBooking\Extension\Booking;
|
||||
|
||||
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 Booking($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuitebooking'));
|
||||
$plugin->setApplication(\Joomla\CMS\Factory::getApplication());
|
||||
return $plugin;
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,163 @@
|
||||
--
|
||||
-- MokoSuite Booking Tables
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_locations` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`address` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`city` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`state` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`postal_code` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
`country` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`timezone` VARCHAR(50) NOT NULL DEFAULT 'America/New_York',
|
||||
`phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`photo` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`notes` TEXT,
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
`ordering` INT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
`created_by` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_services` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT,
|
||||
`category` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`duration_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 30,
|
||||
`buffer_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`currency` VARCHAR(3) NOT NULL DEFAULT 'USD',
|
||||
`max_attendees` SMALLINT UNSIGNED NOT NULL DEFAULT 1,
|
||||
`requires_deposit` TINYINT NOT NULL DEFAULT 0,
|
||||
`deposit_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`color` VARCHAR(7) NOT NULL DEFAULT '#3788d8',
|
||||
`photo` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
`ordering` INT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
`created_by` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_category` (`category`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_staff` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`contact_id` INT DEFAULT NULL,
|
||||
`user_id` INT DEFAULT NULL,
|
||||
`display_name` VARCHAR(255) NOT NULL,
|
||||
`title` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`bio` TEXT,
|
||||
`photo` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`color` VARCHAR(7) NOT NULL DEFAULT '#3788d8',
|
||||
`services_json` JSON DEFAULT NULL,
|
||||
`locations_json` JSON DEFAULT NULL,
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
`ordering` INT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_contact` (`contact_id`),
|
||||
KEY `idx_user` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_schedules` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`staff_id` INT UNSIGNED NOT NULL,
|
||||
`location_id` INT UNSIGNED DEFAULT NULL,
|
||||
`day_of_week` TINYINT UNSIGNED NOT NULL,
|
||||
`start_time` TIME NOT NULL,
|
||||
`end_time` TIME NOT NULL,
|
||||
`effective_from` DATE DEFAULT NULL,
|
||||
`effective_until` DATE DEFAULT NULL,
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_staff` (`staff_id`),
|
||||
KEY `idx_location` (`location_id`),
|
||||
KEY `idx_day` (`day_of_week`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_availability_overrides` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`staff_id` INT UNSIGNED NOT NULL,
|
||||
`override_date` DATE NOT NULL,
|
||||
`available` TINYINT NOT NULL DEFAULT 0,
|
||||
`start_time` TIME DEFAULT NULL,
|
||||
`end_time` TIME DEFAULT NULL,
|
||||
`reason` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_staff_date` (`staff_id`, `override_date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_bookings` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`booking_ref` VARCHAR(20) NOT NULL,
|
||||
`contact_id` INT DEFAULT NULL,
|
||||
`staff_id` INT UNSIGNED DEFAULT NULL,
|
||||
`location_id` INT UNSIGNED DEFAULT NULL,
|
||||
`customer_name` VARCHAR(255) NOT NULL,
|
||||
`customer_email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`customer_phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`booking_date` DATE NOT NULL,
|
||||
`start_time` TIME NOT NULL,
|
||||
`end_time` TIME NOT NULL,
|
||||
`status` ENUM('pending','confirmed','in_progress','completed','cancelled','no_show') NOT NULL DEFAULT 'pending',
|
||||
`total_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`deposit_paid` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`payment_status` ENUM('unpaid','partial','paid','refunded') NOT NULL DEFAULT 'unpaid',
|
||||
`notes` TEXT,
|
||||
`internal_notes` TEXT,
|
||||
`source` ENUM('admin','website','api','walk_in') NOT NULL DEFAULT 'admin',
|
||||
`cancelled_at` DATETIME DEFAULT NULL,
|
||||
`cancellation_reason` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`reminder_sent` TINYINT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
`created_by` INT NOT NULL DEFAULT 0,
|
||||
`modified` DATETIME DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_ref` (`booking_ref`),
|
||||
KEY `idx_contact` (`contact_id`),
|
||||
KEY `idx_staff` (`staff_id`),
|
||||
KEY `idx_location` (`location_id`),
|
||||
KEY `idx_date` (`booking_date`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_booking_services` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`booking_id` INT UNSIGNED NOT NULL,
|
||||
`service_id` INT UNSIGNED NOT NULL,
|
||||
`staff_id` INT UNSIGNED DEFAULT NULL,
|
||||
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`duration_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 30,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_booking` (`booking_id`),
|
||||
KEY `idx_service` (`service_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_waitlist` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`contact_id` INT DEFAULT NULL,
|
||||
`service_id` INT UNSIGNED NOT NULL,
|
||||
`staff_id` INT UNSIGNED DEFAULT NULL,
|
||||
`location_id` INT UNSIGNED DEFAULT NULL,
|
||||
`customer_name` VARCHAR(255) NOT NULL,
|
||||
`customer_email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`customer_phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`preferred_date_start` DATE DEFAULT NULL,
|
||||
`preferred_date_end` DATE DEFAULT NULL,
|
||||
`preferred_time_start` TIME DEFAULT NULL,
|
||||
`preferred_time_end` TIME DEFAULT NULL,
|
||||
`status` ENUM('waiting','notified','booked','expired','cancelled') NOT NULL DEFAULT 'waiting',
|
||||
`notified_at` DATETIME DEFAULT NULL,
|
||||
`notes` TEXT,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_service` (`service_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -0,0 +1,12 @@
|
||||
--
|
||||
-- MokoSuite Booking — Uninstall
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_waitlist`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_booking_services`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_bookings`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_availability_overrides`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_schedules`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_staff`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_services`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_locations`;
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Plugin\System\MokoSuiteBooking\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
|
||||
class Booking extends CMSPlugin implements SubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<extension type="plugin" group="webservices" method="upgrade">
|
||||
<name>Web Services - MokoSuite Booking</name>
|
||||
<element>mokosuitebooking</element>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting.</copyright>
|
||||
<version>06.00.00</version>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>REST API routes for MokoSuite Booking operations</description>
|
||||
<namespace path="src">Moko\Plugin\WebServices\MokoSuiteBooking</namespace>
|
||||
<files><folder>src</folder><folder>services</folder></files>
|
||||
</extension>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Moko\Plugin\WebServices\MokoSuiteBooking\Extension\MokoSuiteBooking;
|
||||
|
||||
return new class implements ServiceProviderInterface {
|
||||
public function register(Container $container): void {
|
||||
$container->set(PluginInterface::class, function (Container $container) {
|
||||
$dispatcher = $container->get(DispatcherInterface::class);
|
||||
return new MokoSuiteBooking($dispatcher, (array) PluginHelper::getPlugin('webservices', 'mokosuitebooking'));
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Plugin\WebServices\MokoSuiteBooking\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\CMS\Router\ApiRouter;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
|
||||
class MokoSuiteBooking extends CMSPlugin implements SubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'onBeforeApiRoute' => 'onBeforeApiRoute',
|
||||
];
|
||||
}
|
||||
|
||||
public function onBeforeApiRoute($event): void
|
||||
{
|
||||
$router = $event->getArgument('router');
|
||||
|
||||
$routes = [
|
||||
'services', 'staff', 'bookings', 'schedules',
|
||||
'locations', 'availability', 'waitlist',
|
||||
];
|
||||
|
||||
foreach ($routes as $route) {
|
||||
$router->createCRUDRoutes(
|
||||
"v1/booking/{$route}",
|
||||
$route,
|
||||
['component' => 'com_mokosuitebooking']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="package" method="upgrade">
|
||||
<name>Package - MokoSuite Booking</name>
|
||||
<packagename>mokosuitebooking</packagename>
|
||||
<version>06.00.00</version>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<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>Appointment and resource booking for service businesses</description>
|
||||
<php_minimum>8.3</php_minimum>
|
||||
<dlid prefix="dlid=" suffix=""/>
|
||||
<blockChildUninstall>true</blockChildUninstall>
|
||||
<files folder="packages">
|
||||
<file type="plugin" id="plg_system_mokosuitebooking" group="system">plg_system_mokosuitebooking.zip</file>
|
||||
<file type="component" id="com_mokosuitebooking">com_mokosuitebooking.zip</file>
|
||||
<file type="plugin" id="plg_webservices_mokosuitebooking" group="webservices">plg_webservices_mokosuitebooking.zip</file>
|
||||
</files>
|
||||
<updateservers>
|
||||
<server type="extension" priority="1" name="Package - MokoSuite Booking">https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBooking/updates.xml</server>
|
||||
</updateservers>
|
||||
</extension>
|
||||
Reference in New Issue
Block a user