POS

Complete inventory management and point-of-sale system for your Larapen site. Track stock across multiple warehouses, process sales via a built-in POS, manage cash registers, and monitor inventory with real-time alerts and comprehensive reports.

Multi-Warehouse Inventory

Track stock across multiple warehouses/locations with per-warehouse quantities, reorder levels, and bin locations.

Stock Movements

Record all stock changes: receive, dispatch, transfer between warehouses, and inventory adjustments with full audit trail.

Sales Terminal

Full-screen cash register with product search, barcode scanning, cart management, and payment processing.

Cash Registers

Track cashier sessions with opening/closing amounts, expected vs counted cash, and automatic discrepancy detection.

Stock Alerts

Automatic low stock notifications when quantities drop below reorder levels. Email and database notifications.

Reports & Analytics

Dashboard with sales charts, stock valuation reports, movement analysis, and top-selling product rankings.

Use Cases

Retail Store Management

Track inventory in-store and in warehouse, process sales via POS, monitor stock levels. Get alerts when products run low and analyze sales trends with built-in reports.

Warehouse Operations

Multi-location inventory with transfers, adjustments, and comprehensive movement logging. Track every stock change with an immutable audit trail across all your warehouses.

Restaurant / Cafe

Manage ingredient stock with unit tracking (kg, liters, pieces), receive deliveries, track usage. Use the POS for front-of-house sales and monitor ingredient levels.

Requirements

  • Larapen CMS v1.0.0 or later
  • PHP 8.3+
  • MySQL 8.0+
Note: This is an admin-only add-on — it does not provide any front-end pages. All functionality is accessed through the admin panel.

Installation

Step 1: Place the Add-on

Copy or symlink the pos folder into your Larapen "extensions/addons" directory:

Step 2: Activate the Add-on

Go to Admin → Add-ons → Installed Add-ons and activate POS.

Step 3: Run Migrations

This creates the following tables: pos_products, pos_warehouses, pos_warehouse_product, pos_movements, pos_registers, pos_sales, pos_sale_items, and pos_alerts. Product categories use the core categories table with categorizable_type = 'pos_product'.

Step 4: Set Permissions

The add-on registers 26 permissions (see Permissions). Assign them to admin roles via Admin → Users → Roles & Permissions.

Step 5: Configure

Navigate to Admin → POS → Settings and configure tax rates, currency, SKU generation, alerts, and receipt options. See Configuration.

Configuration

All settings are managed in Admin → POS → Settings (stored in the settings table, group pos). Defaults are defined in config/pos.php.

General

Setting Description Default
pos_default_tax_rate Tax percentage applied to POS sales. 0
pos_currency_symbol Currency symbol displayed on prices and receipts. $

SKU & Barcode

Setting Description Default
pos_auto_generate_sku Automatically create a SKU for new products. true
pos_sku_prefix Prefix for auto-generated SKUs (e.g. STK-000001). STK
pos_barcode_enabled Enable barcode field on products and barcode scanning in the POS. true

Alerts

Setting Description Default
pos_low_pos_alerts_enabled Enable automatic low stock alert creation when quantities drop below reorder levels. true
pos_large_adjustment_threshold Quantity threshold for triggering large adjustment notifications. 50

Sales & Receipts

Setting Description Default
pos_sale_number_prefix Prefix for generated sale numbers (e.g. SALE-000001). SALE
pos_receipt_header Custom text displayed at the top of printed receipts. (empty)
pos_receipt_footer Custom text displayed at the bottom of printed receipts. (empty)

Environment Variables

POS_DEFAULT_TAX_RATE=0
POS_CURRENCY_SYMBOL=$
POS_AUTO_GENERATE_SKU=true
POS_SKU_PREFIX=STK
POS_BARCODE_ENABLED=true
POS_LOW_POS_ALERTS=true
POS_LARGE_ADJUSTMENT_THRESHOLD=50
POS_SALE_PREFIX=SALE
Note: Environment variables are used as defaults. Settings saved in the admin panel override them.

Admin: Dashboard

The POS dashboard (POS → Dashboard) is the landing page for daily POS operations. It provides a quick overview of key metrics and fast access to common tasks.

KPI Cards

Six summary cards at the top of the page:

  • Total Products: number of active POS products.
  • Stock Value: total value of all inventory (cost price × quantity).
  • Low Stock Alerts: count of active low stock alerts.
  • Today’s Sales: number of sales completed today.
  • Today’s Revenue: total revenue from today’s sales.
  • Open Registers: number of currently open cash registers.

Quick Actions

One-click buttons for the most common operations:

  • Open Terminal: jump to the sales terminal.
  • Open Register: start a new register session.
  • New Movement: record a stock movement.
  • New Product: create a product.
  • View Reports: go to the reports page.

Recent Activity

  • Recent Sales: the last 5 sales with sale number, amount, status, and date.
  • Recent Movements: the last 5 stock movements with product, type, quantity, and date.

Admin: Products

The Products page (POS → Products) manages your inventory catalog.

Products List

A paginated table showing:

  • Name
  • SKU
  • Barcode
  • Unit (piece, kg, g, liter, meter, box, pack)
  • Cost Price
  • Selling Price
  • Total Stock (sum across all warehouses)
  • Status (active / inactive)

Per-item actions: Edit, Delete. Bulk delete with checkbox selection. Soft-deleted products can be restored.

Creating & Editing Products

The product form includes the following fields:

  • Name (translatable): product title displayed throughout the admin.
  • Slug (translatable): URL-friendly identifier. Auto-generated from name if empty.
  • Description (translatable): detailed product description.
  • SKU: stock keeping unit. Auto-generated if pos_auto_generate_sku is enabled.
  • Barcode: optional barcode value for POS scanning.
  • Unit: measurement unit — piece, kg, g, liter, meter, box, or pack.
  • Cost Price: purchase/manufacturing cost (used for valuation reports).
  • Selling Price: retail price used in POS sales.
  • Category: select from POS product categories.
  • Featured Image: product image via the media library.
  • Active toggle: inactive products are hidden from the POS and reports.

SKU & Barcode

When pos_auto_generate_sku is enabled, new products automatically receive a SKU using the format {prefix}-{zero-padded ID} (e.g. STK-000042). You can override the auto-generated SKU at any time.

When pos_barcode_enabled is enabled, a barcode field appears on the product form. Barcodes are used for quick product lookup in the POS via barcode scanner.

Admin: Categories

Product categories use the unified categories table with categorizable_type = 'pos_product'. Categories are managed via POS → Categories.

  • Name (translatable) and Slug (translatable, auto-generated).
  • Description (translatable).
  • Parent Category: supports hierarchical nesting.
  • Position: ordering value.
  • Is Active toggle.

Admin: Warehouses

The Warehouses page (POS → Warehouses) manages your storage locations.

Warehouse Fields

  • Name (translatable): warehouse display name.
  • Code: unique identifier code (e.g. WH-MAIN, WH-EAST).
  • Address, City, Country: physical location.
  • Phone and Email: contact information.
  • Default toggle: marks this as the default warehouse for new stock movements and POS sales.
  • Active toggle: inactive warehouses are excluded from movement forms and POS.
  • Assigned Users: select which admin users can access this warehouse. Users not assigned to any warehouse can access all warehouses by default.

Warehouses are soft-deleted and can be restored.

Default Warehouse

Exactly one warehouse should be marked as the default. The default warehouse is pre-selected in stock movement forms and used as the source warehouse for POS sales. If no default is set, the first active warehouse is used.

Warehouse Access Control

You can restrict which warehouses a user can access by assigning them to specific warehouses on the warehouse edit page. This controls what data they see across the entire POS module:

  • Assigned users can only view and interact with data (registers, sales, movements, alerts, reports) from their assigned warehouses.
  • Users with no assignment (i.e. not assigned to any warehouse) can access all warehouses by default.
  • Users with the pos.warehouses.access_all permission bypass all warehouse filtering and can access everything regardless of assignments.

The filtering is applied automatically to all POS pages: warehouses list, registers, sales, stock movements, alerts, reports, and the sales terminal.

Tip: To restrict a user to a single warehouse, assign them to that warehouse only. To give a manager access to all warehouses, either leave them unassigned or grant the pos.warehouses.access_all permission.

Admin: Stock Movements

The Stock Movements page (POS → Movements) displays an immutable audit trail of all inventory changes.

Movement Types

Type Description Effect
In Stock received (purchase, delivery). +quantity in destination warehouse
Out Stock removed (waste, damage, write-off). −quantity in source warehouse
Transfer Stock moved between warehouses. −source, +destination
Adjustment Correct quantity after physical count. Sets to new value
Sale POS sale (created automatically). −quantity
Return Sale void (created automatically). +quantity

Creating Movements

To create a manual movement:

  1. Select the movement type (In, Out, Transfer, or Adjustment).
  2. Select the product.
  3. Select the warehouse(s) — source and/or destination depending on the type.
  4. Enter the quantity.
  5. Optionally add a reference (e.g. purchase order number) and notes.

The form dynamically adjusts based on the selected movement type (e.g. Transfer shows both source and destination warehouse fields).

Important: Movements are immutable audit records. Once created, they cannot be edited or deleted. To correct a mistake, create a new Adjustment movement.

Filters

The movement list can be filtered by: type, product, warehouse, and date range.

Admin: Sales Terminal

The Sales Terminal (POS → Terminal) provides a full-screen cash register interface for processing sales directly from the admin panel.

Prerequisite: You must have an open register before accessing the POS. If no register is open, you will be prompted to open one.

Using the POS

The POS uses a two-panel layout:

  • Left panel: product search and cart. Search by product name, SKU, or barcode. Click a product to add it to the cart. Adjust quantities or remove items inline.
  • Right panel: payment processing. Select payment method (Cash, Card, or Other). For cash payments, enter the amount received to see the change calculation.

Sale Completion

After completing a sale:

  • A sale number is generated using the configured prefix (e.g. SALE-000001).
  • Stock quantities are automatically decreased in the register’s warehouse.
  • Stock movements of type Sale are created for each item.
  • The register’s running totals are updated.
  • A receipt is displayed and can be printed.

Barcode Scanning

When pos_barcode_enabled is enabled, the POS search field auto-detects barcode scanner input. Barcode scanners typically send characters followed by an Enter key, which triggers an automatic product lookup. If a matching product is found, it is immediately added to the cart.

Receipts

After each sale, a receipt is generated containing:

  • Custom header text (from pos_receipt_header setting).
  • Sale number and date/time.
  • Itemized list with quantities, unit prices, and line totals.
  • Subtotal, tax, and total.
  • Payment method and amount.
  • Change due (for cash payments).
  • Custom footer text (from pos_receipt_footer setting).

Admin: Registers

The Registers page (POS → Registers) manages cash register sessions. Each register session tracks a cashier’s shift from open to close.

Opening a Register

  • Select a warehouse — all POS sales during this session are linked to this warehouse.
  • Enter the opening amount — the starting cash in the register.

Only one register can be open per user at a time.

Closing a Register

When closing a register:

  • Enter the counted cash — the actual amount of cash in the register.
  • The system displays the expected amount (opening amount + cash sales).
  • The difference between expected and counted is shown, highlighting any discrepancy.

A Register Closed notification is sent to administrators when a register is closed.

Admin: Sales

The Sales page (POS → Sales) shows all POS transactions.

Sales List

A paginated, filterable table showing sale number, customer, items, total, payment method, status, warehouse, and date. Filter by status, payment method, warehouse, and date range.

Sale Detail

The sale detail page shows:

  • Sale number and date/time.
  • Customer information (if provided).
  • Items table: product name, SKU, quantity, unit price, and line total.
  • Financial summary: subtotal, tax, and total.

Voiding Sales

To void a sale:

  • A reason is required (minimum 10 characters).
  • Stock is automatically reversed — quantities are restored to the warehouse.
  • Return type stock movements are created for each item.
Important: Sales are never deleted from the system. Voided sales remain in the records with their void reason for audit purposes.

Admin: Alerts

The Alerts page (POS → Alerts) displays inventory alerts.

Alerts are automatically created when a product’s quantity in any warehouse drops to or below its reorder level. Alerts have three statuses:

  • Active: stock is below the reorder level.
  • Resolved: stock has been replenished above the reorder level.
  • Dismissed: manually dismissed by an administrator.

Use the Run Stock Check button to perform a global sweep of all products and create/resolve alerts based on current stock levels.

Admin: Reports

The Reports page (POS → Reports) provides analytical charts, tables, and three detailed report types. Use the period filter to adjust the date range.

Overview Charts & Tables

The main reports page shows:

  • Sales Over Time: line chart showing daily sales trends.
  • Movements by Type: doughnut chart breaking down stock movements.
  • Top Selling Products: ranked by quantity sold in the selected period.
  • Stock by Warehouse: total products and quantity per warehouse.

Stock Valuation

Shows the total value of your inventory:

  • Per-product value breakdown by warehouse (cost price × quantity).
  • Grand total across all products and warehouses.

Movement Analysis

Analyze stock movements over a selected period:

  • Period filter: select date range.
  • Doughnut chart: visual breakdown by movement type.
  • Breakdown table: count and total quantity per movement type.

Sales Analysis

Analyze sales performance over a selected period:

  • Period filter: select date range.
  • Line chart: sales trends over time.
  • Payment method pie chart: revenue breakdown by payment method (Cash, Card, Other).
  • Top products: ranked by quantity sold.

Admin: Settings

The settings page (POS → Settings) is organized into sections:

  • General: Default tax rate, currency symbol.
  • SKU & Barcode: Auto-generate SKU, SKU prefix, barcode scanning toggle.
  • Alerts: Low stock alerts toggle, large adjustment threshold.
  • Sales & Receipts: Sale number prefix, receipt header/footer text.

Permissions

The add-on registers 27 permissions:

Permission Description
pos.dashboard.view View POS dashboard
pos.products.view View POS products list
pos.products.create Create new POS products
pos.products.edit Edit existing POS products
pos.products.delete Delete POS products
pos.categories.view View POS categories
pos.categories.create Create POS categories
pos.categories.edit Edit POS categories
pos.categories.delete Delete POS categories
pos.warehouses.view View warehouses
pos.warehouses.create Create new warehouses
pos.warehouses.edit Edit existing warehouses
pos.warehouses.delete Delete warehouses
pos.warehouses.access_all Access all warehouses regardless of assignment
pos.movements.view View POS movements
pos.movements.create Create manual POS movements
pos.registers.view View cash registers
pos.registers.open Open a cash register session
pos.registers.close Close a cash register session
pos.sales.view View POS sales
pos.sales.create Create sales via POS
pos.sales.void Void completed sales
pos.alerts.view View POS alerts
pos.alerts.dismiss Dismiss POS alerts
pos.reports.view Access POS reports
pos.settings.view View POS settings
pos.settings.edit Edit POS settings
Note: All 27 permissions are listed above.

Notifications

The add-on sends 3 notification types (managed via the centralized notification system at Admin → Settings → Notifications):

Notification Trigger Channels
Low Stock Alert Product quantity drops below its reorder level in a warehouse. Mail, Database
Register Closed A cash register session is closed by a cashier. Mail, Database
Large Adjustment A stock adjustment movement exceeds the configured threshold. Mail, Database

Artisan Commands

Command Description
php artisan pos:check-levels Scans all warehouse stock levels and creates/resolves alerts accordingly. Recommended to schedule hourly via Laravel’s task scheduler.

To schedule the command, add it to your routes/console.php:

Schedule::command('pos:check-levels')->hourly();

Troubleshooting

POS not working

  • Ensure you have an open register. The POS requires an active register session before processing sales.
  • Only one register can be open per user at a time. Close the existing register before opening a new one.

Missing stock

  • Movements are immutable — they cannot be edited or deleted once created.
  • To correct stock quantities, create a new movement of type Adjustment.
  • Review the movement history for the product to trace where stock was allocated.

Alerts not triggering

  • Check that pos_low_pos_alerts_enabled is set to true in settings.
  • Ensure the product has a reorder_level greater than 0 set in the warehouse-product pivot.
  • Run php artisan pos:check-levels to manually trigger an alert scan.

Sale numbers not sequential

  • Changing the pos_sale_number_prefix setting resets the sequence counter.
  • Voided sales still consume a sale number — they are not recycled.

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket