Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tomato Pos Module Laravel Package

tomatophp/tomato-pos-module

Point-of-Sale module for TomatoPHP and Laravel that adds a cashier-friendly POS screen, quick product search, cart and checkout flow, receipts, and payment handling, letting you ring up in-store sales directly from your existing Laravel admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

The v1.0.1 release adds an Artisan command for generating POS registers, so the first thing to check after upgrading is php artisan list | grep tomato-pos. The package is a Tomato PHP admin module (Laravel + Filament), so the expected setup is:

  1. composer require tomatophp/tomato-pos-module
  2. php artisan vendor:publish --tag=tomato-pos-module-config (and -migrations if you want to own them)
  3. php artisan migrate
  4. Register the module in your Tomato panel providers (TomatoPosServiceProvider / panel plugin registration), then clear caches: php artisan optimize:clear

Look first at config/tomato-pos-module.php for navigation, route prefixes, and tenant/branch scoping, then at the src/Models and src/Filament directories — those tell you what the module expects from the host app (typically a Company/Branch owner, products, and a user relation for cashiers).

First real use case: create a register, open a session, and attach a cashier. With v1.0.1 you can do it non-interactively:

php artisan tomato-pos:register:generate --name="Main Till" --branch=1

Check php artisan help <command-name> for the exact signature, since the command is new and flags may be minimal. The safest first pass is to create a register in the admin UI to see the required fields, then reproduce it with the command.

Implementation Patterns

Register-as-a-record pattern. Treat registers as first-class records owned by a branch/company, not as config. Seed them per environment with the new generate command so local, staging, and prod all have deterministic tills. Wire it into deployment:

// database/seeders/PosRegisterSeeder.php
public function run(): void
{
    if (app()->environment('production')) {
        return; // registers are managed by ops there
    }
    $this->call('tomato-pos:register:generate', ['--branch' => 1, '--name' => 'Test Till']);
}

Wrap mutations in a service/action. Keep your own PosRegisterService around the package models so that if the command or model API shifts between minor versions, you patch one class instead of fifty Filament callbacks. This is especially worth doing given the API is still pre-1.1.

Session lifecycle hook. POS work is almost always "open session → take sales → close session". Model observers on the session/transaction models are the least invasive integration point; use those rather than overriding the module's Filament pages, which change more often.

Multi-register, multi-branch. If your dashboard hosts several branches, scope the register query at the panel level (Filament::registerTenant() / global scope) rather than filtering inside each resource. The module's own resources will follow tenant scoping if you configure it there, and the generate command then needs a branch/tenant argument too.

Generate command as a dev convenience, not a migration. Use it for local bootstrap and CI fixtures. Do not run it unconditionally in a release pipeline — it should be idempotent-guarded by your own check (e.g. if (! Register::where('name', ...)->exists())) since "generate" commands that insert rows are rarely safe to re-run.

Pair with the parent Tomato modules. Registers need products, taxes, and users. If tomato-products / tomato-orders are installed, hook the register into those via the shared branch_id/company_id foreign keys instead of duplicating product references in the POS module's own tables.

Gotchas and Tips

The new command is under-documented. v1.0.1 adds a first-contribution feature; expect the README to lag the signature. Read the command class (src/Console/ — grep for register:generate) before relying on flag names, and pin the exact patch version in composer.json if you call it from scripts.

Migration ordering with existing POS tables. If you already migrated v1.0.0 tables, v1.0.1's new command may assume columns it never adds. Run php artisan migrate:status and diff database/migrations after upgrading; the release is a command addition, so schema changes are unlikely, but confirm rather than assume.

Commands are not auto-registered on module providers in every Tomato setup. If php artisan list doesn't show it after composer update, verify the service provider binds the command (some modules gate it behind $this->commands([...]) in boot()), then composer dump-autoload and php artisan optimize:clear.

Cache-busting. Module configs are cached. After any config publish or provider change, php artisan config:clear — otherwise your new register settings look inert and you'll debug the wrong layer.

Permissions. New registers still need Filament permission/policy records for cashier roles. Check tomato-roles/permission seeder output; a register created by the command has no role grants, so the UI shows it but the intended operator still gets 403.

Debugging the generate flow. --verbose plus a transaction wrapper in a seeder is the fastest way to isolate failures; if the command silently no-ops, check for an internal exists() guard in the command before opening an upstream issue.

Extension points. Prefer publishing config/migrations over forking resources. If you must customize Filament pages, subclass the module resource and register your subclass in the panel provider — that survives patch upgrades far better than editing vendor/.

Version pin. The package jumped v1.0.0 → v1.0.1 with a single command added, so treat the surface as volatile. "tomatophp/tomato-pos-module": "~1.0.1" keeps patch fixes flowing without picking up a minor break.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib