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 Laravel Package

tomatophp/tomato-pos

Tomato POS is a Laravel package for adding point-of-sale workflows to your app, with modules for products, orders, payments, and receipts. It fits the TomatoPHP ecosystem for building retail or restaurant POS features quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Tomato POS is a Filament-based point-of-sale module for the TomatoPHP admin suite. It is not a standalone package — it expects the TomatoPHP panel (or at minimum a Filament 3 panel) plus the sibling commerce packages that supply products, customers, and orders.

  1. Install the dependencies first, not the POS. In practice you want tomatophp/tomato-admin (or a Filament 3 panel), plus the product/category/customer packages the POS screen reads from. Installing tomatophp/tomato-pos alone gives you an empty till.
  2. Pull the package: composer require tomatophp/tomato-pos.
  3. Run migrations and seeders: php artisan migrate — check the migration file list before running on an existing database (see Gotchas regarding table name collisions).
  4. Register the plugin in your panel provider (->plugin(\TomatoPHP\TomatoPos\TomatoPosPlugin::make()) or the Filament 3 TomatoPos::make() form, depending on the version you resolve). On a TomatoPHP panel this is usually auto-discovered via the plugins config — verify before adding it twice.
  5. Publish what you intend to touch: config, views, translations, and assets. In v1.0.14 the translation files are the headline change, so php artisan vendor:publish and inspect the available tags for tomato-pos before assuming tag names.

Where to look first: config/ (currency, tax, receipt, table prefix), then src/ for the Filament page/resource classes that render the POS screen, then resources/views for the receipt template. Read the migrations early — they tell you more about the data model than the README does.

First use case: ring up a walk-in sale end to end — open the POS page, add two products to the cart, apply a discount, take a cash payment, and print/preview the receipt. That single path exercises the cart state, order creation, payment recording, and the receipt view, and it will surface 90% of configuration problems in an afternoon.

Implementation Patterns

Treat it as a module in a suite, not an app. The POS screen is a thin UI over models owned by other TomatoPHP packages. Your integration work happens at the boundaries: product availability, customer lookup, and order finalisation. Wire your business rules there rather than forking the POS page.

Extending the Filament resources. The supported pattern is subclassing — extend the package's resource/page classes, override form(), table(), getPages(), or the cart action handlers, and register your subclass in the panel instead of the original. This survives patch upgrades far better than editing published views.

Swapping models via config. If the package exposes model bindings in its config (common in the TomatoPHP family), prefer overriding the model class over editing vendor code. Keeps composer update safe.

Hooking order lifecycle. Register observers or model events on the order/order-item models for the things a POS must do beyond the UI: decrement stock, write an audit row, push to accounting, fire a receipt print job. Do this in a service provider rather than inside the POS page so refunds and admin-created orders flow through the same logic.

Localisation (new in v1.0.14). Ship your own locale by publishing the language files and placing overrides in lang/vendor/tomato-pos/{locale}/. Set the panel/locale per user so cashiers get their language without changing the app default. If you serve RTL locales, the v1.0.14 style updates are worth re-testing specifically — cart and receipt layouts are the usual breakage points.

Receipts. Publish the receipt Blade view into your app and own it there. Pass a plain array/DTO into the view rather than the Eloquent model so you can reuse it for reprints, email, and 80mm thermal output without dragging relations along.

Multi-terminal / multi-register. If you run several tills, key the POS session by terminal/register ID and keep cart state per terminal. Livewire cart state in the browser is fine for one till; two cashiers sharing a session is a data-integrity bug waiting to happen.

Testing. Write Livewire tests against the POS page component: add item, change quantity, apply tax, submit. These are cheap and catch the regressions that patch releases in a UI-heavy package tend to introduce.

Gotchas and Tips

  • Generic table names. A POS module creates orders, order_items, payments, accounts-style tables. On a brownfield app this collides. Check the migrations before php artisan migrate and look for a table-prefix config key; if there isn't one, you're renaming migrations and updating the models — do it deliberately, once.
  • Published views shadow upgrades. v1.0.14 changed POS styling. If you published views in an earlier version, those upstream style fixes will silently not apply to you. Either re-publish and re-apply your diffs, or keep published views to the receipt template only.
  • Translation coverage is never 100%. "Add translations" in a release note means the shipped strings, not every string on the screen. Expect to find hardcoded labels, especially in JS-driven cart components, and budget for a grep over the views.
  • Cache clearing after every upgrade. php artisan optimize:clear plus php artisan filament:assets is the fix for a surprising share of "the plugin doesn't appear" reports. Filament's component/panel caching is aggressive.
  • Money as floats. Verify the casts on price/total columns before trusting arithmetic. If anything is a float, do your totals in integer minor units in your own layer and let the package display them. Tax rounding on multi-line carts is where this bites.
  • Cart is ephemeral. Treat an in-progress cart as lost on page reload/network drop unless you've confirmed otherwise. For a real shop counter, that is a support call per incident — consider persisting draft carts yourself.
  • Permissions. The POS pages are Filament resources and will respond to filament-shield/Spatie permissions. Configure roles early; a cashier who can reach the product-edit screen is a liability.
  • Debugging the screen. Because the POS page is Livewire, browser console plus storage/logs/laravel.log covers most issues. If actions silently do nothing, it's usually a swallowed validation error or a policy denial — check canViewAny/canCreate on the resource before assuming a bug.
  • Extension points to prefer, in order: config → model swap via config → subclassed Filament classes → published receipt view → published views (last resort) → vendor edits (never).
  • Pin the version in composer.json ("tomatophp/tomato-pos": "~1.0.14") if you're in production. Patch releases here are UI and translation churn, which is exactly the category most likely to move markup you've styled around.
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.
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
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle