Skip to content

feat(booknetic): add the Booknetic integration - #239

Open
RishadAlam wants to merge 11 commits into
mainfrom
feat/booknetic
Open

RishadAlam wants to merge 11 commits into
mainfrom
feat/booknetic

Conversation

@RishadAlam

@RishadAlam RishadAlam commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Description

Adds the Booknetic integration to the free plugin. This covers the action config UI, the free-side action backend that fires one Pro filter for each action, and the Booknetic entry in the trigger lists. There are 40 Pro write actions for appointments, payments, customers, staff, locations, services, service extras, categories and in-app notifications, plus 14 Pro triggers.

Pro side: https://github.com/bit-apps-pro/bit-integrations-pro/pull/160

Motivation & Context

This ports the Booknetic integration from Bit Flows (Bit-Pi) to Bit Integrations. The port drops the get/list actions and any action or trigger that core Booknetic cannot run:

  • Create Payment Link: the core gateways return no link.
  • Payment Completed and Payment Canceled: only paid add-on gateways fire these.

Main still resolves only {Name}Controller in Flow::isActionExists(). For that reason the action uses BookneticController (execute only), BookneticHelper (routes) and BookneticService (switch + LogHandler::save). Rename the Controller to BookneticAction after the action restructure merges.

Related Links: (if applicable)

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 📚 Documentation update
  • ⚡ Improvement
  • 🔄 Code refactor

Key Changes

Backend

  • Added backend/Actions/Booknetic/:
    • BookneticController::execute().
    • BookneticService: one switch case per action. Each case fires Hooks::apply(Config::withPrefix('booknetic_<action>'), …) and passes only the arguments that action's Pro handler reads. Every path is logged.
    • BookneticHelper::refreshOptions(): serves every dropdown list through one refresh_booknetic_options route. It takes an allow-listed type, sanitized with sanitize_key, and caps each list at 500 rows.
  • Added a try/catch (Throwable) around the dispatch. Booknetic throws on plan limits and invalid slots, and the flow now logs that message instead of failing the request that fired the trigger.
  • Added Booknetic to AllTriggersName.php as a Pro trigger.

Frontend

  • Added AllIntegrations/Booknetic/. staticData.js holds all actions, field maps, required selects, Utilities and per-action notes in one place.
  • Added the decision-rule split:
    • The ID of the record an action changes stays in the field map, so it can be mapped from trigger data.
    • Required options (status, gateway, category, locations, active status) are selects.
    • Optional options sit under Utilities.
  • Added mappable fallbacks. Create Appointment accepts a mapped Customer, Location, Service or Staff ID in place of the list choice, and Create In-App Notification accepts a mapped WordPress User ID. A hint under each select tells the user which one is used.
  • Added short notes on formats and limits, for example the Starts At format and why a delete can be refused.
  • Added the selected value under each Utilities checkbox.
  • Fixed edit mode:
    • Option lists load when the screen opens and are no longer saved in flow_details.
    • Selects remount once their options arrive, so saved choices show.
    • Field definitions come from staticData instead of the copy saved in the flow.
  • Fixed the field-map value bug copied from FluentCart (i < requiredFlds and .label are now .length and .key), in the Booknetic copy only.
  • Added registration in NewInteg, EditInteg, IntegInfo, SelectAction, tutorialLinks and customFormIntegrations. The last one lets flows with a Booknetic trigger open in edit mode.
  • Added the booknetic.webp logo.

Testing

All tests ran end to end in the browser on a local site with Booknetic 5.2.2:

  • Triggers: Customer Created/Updated/Deleted, Staff Created/Updated and Appointment Created, Updated, Deleted, Status Changed and Rescheduled were fired from Booknetic admin and from a real front-end booking. Payment Confirmed was fired from Booknetic Payments. In each case the fetch captured the fields.
  • Customer panel triggers: Customer Signed Up, Forgot Password and Reset Password cannot run on an unlicensed Booknetic, because Booknetic's own token generation throws "Illegal version of Booknetic detected". I fired the hooks with Booknetic's exact arguments instead. Each one captured 14 customer fields and no token.
  • Actions: all 40 ran through flows fired by real Booknetic events.
    • Each success was checked against the database.
    • The refusal paths return clear messages, for example deleting a category that is still in use.
  • UI: I opened all 40 action screens in the editor and checked each one for selects, required rows, Utilities and notes. Edit mode was re-checked for both wizard-created and saved flows.
  • Checks: eslint --max-warnings=0, prettier --check, php-cs-fixer (repo config), php -l and vite build all pass.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Tests added/updated
  • Documentation updated if needed
  • README updated if needed

Changelog

  • New Integration
    • Booknetic: 14 new triggers for appointments, payments, customers and staff (Pro).
    • Booknetic: 40 new actions to create, update, reschedule, duplicate and delete appointments, payments, customers, staff, locations, services, service extras and categories, and to send in-app notifications (Pro).

🤖 Generated with Claude Code

Controller runs the flow, Helper serves the dropdown lists through one
refresh_booknetic_options route, and Service fires one Pro filter per
action and logs every result.
Required options render as selects, optional options sit under
Utilities, and record IDs stay in the field map so flows can map them.
SetEditIntegComponents only loads the custom form trigger fields for
entities in customFormIntegrations.
Booknetic throws on limits and invalid slots. The flow now logs the
message instead of failing the request that fired the trigger. Option
lists stop at 500 rows.
Create Appointment and Create In-App Notification accept a mapped ID in
place of the list choice, and each action shows a short note on formats
and limits. Option lists load on demand and are no longer saved in the
flow. Parallel list loads share one loader.
Core Booknetic gateways return no link, so the action always failed.
Only paid add-on gateways create links.
The select reads its value only on mount, so it now remounts after its
options load. Field definitions come from staticData instead of the
copy saved in the flow. Utilities show the chosen value under each
option.
Copilot AI balanced review requested due to automatic review settings October 18, 2026 04:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

Update Payment asked for a JSON object of every price key, which a
flow cannot build. It now takes a Service Price number. Also removes
explanatory comments from the Booknetic files.
Copilot AI balanced review requested due to automatic review settings October 18, 2026 05:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI balanced review requested due to automatic review settings November 3, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants