{{ pageTitle.group }}
{{ pageTitle.label }}
{{ (user?.username||'?')[0].toUpperCase() }}
{{ user?.username }}
{{ user?.role }}
{{ banner.msg }}

Dashboard

Drag any widget to rearrange · use Widgets to show/hide.

Products List

Display all products.

NameSkuCategoryStatus PriceStock
{{ p.name }} variants {{ p.sku }} {{ catName(p.category_id) }} {{ p.status }} {{ money(p.units[0]?.sale_price) }} {{ p.units[0]?.quantity||0 }}
No products
displaying {{ filtered(products,['name','sku']).length }} of {{ products.length }} items «1»

Categories

Manage product categories.

Name
{{ cat.name }}
No categories
displaying {{ categories.length }} of {{ categories.length }} items «1»

Taxes

Tax groups and their taxes.

Tax groups
{{ g.name }}{{ (g.taxes||[]).length }} taxes
No tax groups
Taxes

Units

Selling / measurement units.

UnitGroupValue
No units

Unit Groups

Groups of related units.

NameUnits
{{ g.name }}{{ (g.units||[]).length }}
No unit groups

Payment Types

Accepted tender types at the POS.

LabelIdentifier
{{ pt.label }}{{ pt.identifier }}
No payment types (defaults: cash, mpesa, card, account)

Print Labels

Print Code128 barcode labels for products.

ProductSKUPrice
{{ p.name }}{{ p.sku }}{{ money(p.units[0]?.sale_price) }}

Stock Adjustment

Correct on-hand quantities (stock-take).

Stock Flow Records

Immutable stock movement ledger.

WhenActionQtyBeforeAfterReference
{{ (m.at||'').slice(0,16).replace('T',' ') }} {{ m.action }} {{ m.quantity }}{{ m.before }}{{ m.after }}{{ m.reference }}
No stock movements

Assigned Orders

Dine-in & delivery orders and their assignee.

CodeTypeFulfilmentAddressTotalAssignee
{{ o.code }}{{ o.type }} {{ o.process_status }}{{ o.delivery_address||'—' }} {{ money(o.total) }}
No dine-in / delivery orders

Accounts

Chart of accounts.

CodeNameType
{{ a.code }}{{ a.name }}{{ a.type }}
No accounts

Rules

Automated accounting rules — book an account on an event.

NameEventAccountNote
{{ r.name }}{{ r.on_event }}{{ r.account }}{{ r.note }}
No rules

Scale Range

Configure weighing-scale barcodes parsed at the POS.

Example: a barcode {{ scaleForm.prefix }}00042001500 → prefix {{ scaleForm.prefix }}, product code (next {{ scaleForm.product_digits }} digits), then {{ scaleForm.value_digits }} digits of {{ scaleForm.value_type }}. The till parses this on scan.

Modules

Installed modules in this NakalaPOS build.

{{ m.name }}
{{ m.desc }}
Active · built-in
NamePhoneERP NoPointsAccount balance
{{ c.first_name }} {{ c.last_name }} {{ c.phone }}{{ c.erp_customer_no || '—' }} {{ c.loyalty_points }} {{ money(c.account_balance) }}
No customers
displaying {{ filtered(customers,['first_name','last_name','phone']).length }} of {{ customers.length }} items «1»
{{ g.name }}{{ g.reward_ratio }} pts / unit spent
No groups
CodeTypeValueMinUsed
{{ cp.code }}{{ cp.discount_type }}{{ cp.value }}{{ money(cp.minimum_order) }}{{ cp.used_count }}/{{ cp.usage_limit||'∞' }}
No coupons
{{ custDetail.customer }}
Account balance
{{ money(custDetail.account_balance) }}
Loyalty points
{{ custDetail.loyalty_points }}
Account statement
DateRefDebitCreditBalance
{{ (e.date||'').slice(0,10) }}{{ e.reference }} {{ e.debit?money(e.debit):'' }}{{ e.credit?money(e.credit):'' }} {{ money(e.balance) }}
No account activity
Income
{{ money(cashflow.income) }}
Expenses
{{ money(cashflow.expenses) }}
Net
{{ money(cashflow.net) }}
Record expense
DescriptionAccountTypeAmount
{{ e.description }} · {{ e.period_key }} {{ e.account }}{{ e.is_recurring?('template · '+e.recurrence):'one-off' }} {{ money(e.amount) }}
No expenses
Transactions
displaying {{ expenses.length }} of {{ expenses.length }} items «1»

Orders

Display all orders.

CodeTypeFulfilmentPaymentTotalBalance
{{ o.code }}{{ o.type }} {{ o.process_status }} {{ o.payment_status }} {{ money(o.total) }} {{ money(o.balance_due) }}
No orders
displaying {{ filtered(orders,['code','type']).length }} of {{ orders.length }} items «1»

Reconciliation

Cash-up & release staged mobile-vehicle sales to the ERP.

Nothing to reconcile — no staged sales awaiting release.

Sales from stage-mode locations (route vans) collect here until you release them.

{{ g.location.name }}
{{ g.location.code }} → BC {{ g.location.bc_location_code||'—' }} · {{ g.count }} sale(s)
Sales total
{{ money(g.total) }}
Cash
{{ money(g.cash) }}
Non-cash
{{ money(g.noncash) }}
OrderWhenCustomerCashNon-cashTotal
{{ o.code }} {{ o.created_at? new Date(o.created_at).toLocaleString():'' }} {{ o.customer_no||'Walk-in' }} {{ money(o.cash) }}{{ money(o.noncash) }} {{ money(o.total) }}
Cash-up
Expected cash{{ money(g.cash) }}
Variance{{ money(cashVariance(g)) }}

Refunds

All credit notes & returns.

RefundOrderMethodReasonAmountERP Doc
{{ r.code }} {{ r.order_code }}{{ r.method }} {{ r.reason }} -{{ money(r.total) }} {{ r.erp_document_no || '—' }}
No refunds
Refunds
displaying {{ filtered(refunds,['code','order_code','reason']).length }} of {{ refunds.length }} items «1»

Organizations

Every company runs on this one URL, fully isolated from the others.

Create a new organization

OrganizationSlugERPStatusActions
{{ t.name }}{{ t.slug }} {{ t.erp_provider }} {{ t.is_active?'Active':'Suspended' }}
No organizations
Organizations
displaying {{ tenants.length }} of {{ tenants.length }} items
{{ orderDetail.code }} {{ orderDetail.type }}
{{ l.quantity }} × {{ l.name }}{{ money(l.total_price) }}
Total{{ money(orderDetail.total) }}
Paid{{ money(orderDetail.paid_amount) }}
Balance due{{ money(orderDetail.balance_due) }}
Fulfilment
New purchase order
CodeSupplierStatusPaymentTotalActions
{{ po.code }}{{ po.supplier }} {{ po.status }} {{ po.payment_status }} {{ money(po.total_cost) }}
No purchase orders
Purchase orders
displaying {{ pos.length }} of {{ pos.length }} items «1»
NameContactPhoneBalance owed
{{ s.name }}{{ s.contact_name }}{{ s.phone }} {{ money(s.balance) }}
No suppliers
Suppliers
displaying {{ suppliers.length }} of {{ suppliers.length }} items «1»
UsernameFull nameRoleStatus
{{ u.username }}{{ u.full_name }} {{ roleName(u.role) }} {{ u.is_active?'Active':'Disabled' }}
No users
displaying {{ users.length }} of {{ users.length }} items «1»
{{ r.name }} {{ r.slug }}
all access
{{ group }}
{{ repRange.start||'beginning' }} → {{ repRange.end||'today' }}
Gross sales
{{ money(sales.gross_sales) }}
Net sales
{{ money(sales.net_sales) }}
Gross profit
{{ money(profit.gross_profit) }}
{{ profit.margin_pct }}% margin
Tax collected
{{ money(taxRep.tax_collected) }}
Refunds
{{ money(sales.refund_total) }}
Sales by category
{{ r.category }}{{ r.qty }}{{ money(r.revenue) }}
Best products
{{ r.name }}{{ r.qty }} sold{{ money(r.profit) }}
Sales summary
Orders{{ sales.order_count }}
Gross sales{{ money(sales.gross_sales) }}
Refunds-{{ money(sales.refund_total) }}
Net sales{{ money(sales.net_sales) }}
Daily breakdown
DateOrdersGross
{{ r.date }}{{ r.orders }}{{ money(r.gross) }}
No sales in range
Profit & margin
Revenue{{ money(profit.revenue) }}
Cost of goods{{ money(profit.cost_of_goods) }}
Gross profit{{ money(profit.gross_profit) }}
Margin{{ profit.margin_pct }}%
Sales by category — {{ money(byCat.total_revenue) }}
CategoryQtyRevenue
{{ r.category }}{{ r.qty }}{{ money(r.revenue) }}
Best products
ProductQtyRevenueProfit
{{ r.name }}{{ r.qty }}{{ money(r.revenue) }}{{ money(r.profit) }}
Payments by method
{{ m.identifier }}{{ m.count }}×{{ money(m.total) }}
Stock valuation — {{ money(stock.total_stock_value) }}
{{ l.product }}{{ l.on_hand }}{{ money(l.stock_value) }}
Low stock ({{ (lowStock.items||[]).length }})
{{ r.product }}{{ r.on_hand }}
All stocked
Tax report
Net sales{{ money(taxRep.net_sales) }}
Tax collected{{ money(taxRep.tax_collected) }}
Gross sales{{ money(taxRep.gross_sales) }}
Cash flow
Income{{ money(cashflow.income) }}
Expenses-{{ money(cashflow.expenses) }}
Net{{ money(cashflow.net) }}
Customers statement — total {{ money(custStmt.total_spend) }}
CustomerOrdersSpendAcct balancePoints
{{ r.customer }}{{ r.orders }}{{ money(r.spend) }}{{ money(r.account_balance) }}{{ r.loyalty_points }}
Walk-in{{ custStmt.walk_in?.orders||0 }}{{ money(custStmt.walk_in?.spend) }}
No customer sales in range
Monthly sales — {{ yearly.year }} ({{ money(yearly.total) }})
{{ monthLabel(i) }}
Currencies
{{ cu.code }} {{ cu.symbol }}{{ cu.is_base?'base':('× '+cu.rate) }}
No currencies configured
Media library
{{ m.filename }}
No media yet

{{ connMsg }}

Auto-post & payment mapping

On payment the sale posts automatically as a Sales Invoice — Dr Customer / Cr Items (revenue) — then the tender settles it Dr Bank/Cash / Cr Customer. A failed post never blocks the sale; it raises a notification and stays retryable.

Locations

Branch bookshops, mobile-vehicle route bookshops & how each posts to the ERP.

Direct

Posts the invoice and the payment to the ERP immediately. For trusted front-desk tills.

Reconcile

Posts the invoice now but stages the payment for HQ cash-verification before it's booked.

Stage

Holds the whole sale locally — nothing posts until HQ releases it (mobile/vehicle route cash-up).

LocationCodeTypeBC codePostingStatus
{{ l.name }}{{ l.code }} {{ l.type }} {{ l.bc_location_code || '—' }} {{ l.posting_mode }} {{ l.is_active?'Active':'Inactive' }}
No locations yet — create one or Pull from BC.
Locations
displaying {{ locations.length }} of {{ locations.length }} items
{{ locEdit.id?'Edit location':'New location' }}

{{ modalErr }}

Notifications
{{ n.kind.replace('_',' ') }}
{{ n.message }}
All clear
{{ edit.name }}
Details
Image
Selling units
{{ u.unit_name||'Unit' }} · {{ money(u.sale_price) }} · {{ u.quantity }} on hand
Variations
{{ v.variation_name }} · {{ v.sku }} · {{ money(v.units[0]?.sale_price) }}
{{ modal.title }}

{{ modalErr }}