Overview

SmartVend Documentation

SmartVend is an enterprise-grade stock management and point-of-sale system for businesses that sell physical goods — retail chains, wholesale distributors, food producers, and multi-branch SMEs. Manage inventory, sales, purchases, finances, and TRA/VFD tax compliance from one platform across all your warehouse locations — with full double-entry accounting and a complete audit trail.

Laravel 10 Vue.js 2.7 REST API VFD / TRA Compliant Multi-Warehouse Double-Entry Accounting Full Audit Trail

Dashboard

KPIs & charts

Products

Catalog & stock

Sales

Invoices & payments

POS

Point of Sale

Purchases

Supplier orders

Clients

Customers & suppliers

VFD / TRA

Tax compliance

Reports

Analytics & exports

Warehouses

Multi-location stock

Users & Roles

Access control

Expenses

Cost tracking

Accounts

Chart of accounts

Transfers

Inter-warehouse

PO & GRN

Receiving goods

Adjustments

Stock corrections

Collections

Cash tracking

Audit Logs

Activity trail

Settings

System config

Who Is This System For?

SmartVend is built for any business that buys, stocks, and sells physical goods — from a single-location shop to a multi-branch enterprise. If you need to track inventory, invoice customers, pay suppliers, reconcile cash, and produce financial reports, SmartVend gives you one integrated platform to do it all.

Business Types

  • Retail chains & branches — multiple store locations with shared catalog, combined reporting, and per-branch stock control
  • Wholesale & distribution — bulk invoicing for corporate buyers, credit limits, receivables aging, and supplier payment tracking
  • Food & FMCG businesses — perishable stock alerts, batch receiving via GRN, product variants, and promotional pricing
  • Manufacturing with a sales arm — receive raw materials via GRN, track finished goods, sell via invoices or POS counter
  • Service businesses selling products — pharmacies, clinics, repair shops that stock and sell retail items alongside services

Roles That Benefit Most

  • Business owners — live profit, stock value, and outstanding balances from any device, any time
  • Accountants & finance teams — automatic double-entry journals, P&L statements, and chart of accounts — no manual bookkeeping
  • Warehouse managers — approve stock movements, run physical counts, control transfers and adjustments
  • Sales staff — create invoices, record payments, send documents by email or SMS with one click
  • Cashiers — fast POS checkout with barcode scanning, split payments, and automatic tax receipt generation

Key Problems SmartVend Solves

ProblemHow SmartVend Fixes It
"I don't know how much stock I have at each branch"Real-time per-warehouse stock levels, low-stock alerts, and full stock movement history per product
"Customers owe me money and I lose track"Client statements, credit limits, aging balances, and one-click payment recording
"I can't trust my staff without visibility"Every action is logged with the user's name, IP address, and before/after values — tamper-evident audit trail
"My bookkeeper charges a lot for basic journals"Every transaction auto-posts double-entry journal entries — no external accounting software required
"Tax receipts take too long or I miss submissions"VFD/TRA receipts submitted in real time on every POS sale and invoice
"Moving stock between branches is disorganised"Multi-step transfer workflow — stock only moves when both ends confirm; full status trail
"Staff can see things they shouldn't"Granular role-based permissions — cashiers see only POS; accountants see only finance; managers control everything
Example: Typical Multi-Branch Setup
BranchCodeRole in BusinessTypical Daily Volume
Main WarehouseMAINCentral hub — primary receiving, wholesale dispatch, finance control20–50 invoices, GRNs, supplier payments
North BranchNORTHRetail outlet — walk-in counter and local B2B customers30–80 POS transactions, cash collections
South BranchSOUTHRetail counter and area wholesale delivery25–60 POS transactions, stock transfers in
East DepotEASTRegional depot — restocked weekly from main warehouse via transfers10–30 wholesale invoices

Architecture

Backend

  • Laravel 10 (PHP 8.1+) REST API
  • Laravel Passport OAuth2 authentication
  • MySQL database with soft deletes
  • Policy-based authorization (48 policies)
  • Double-entry accounting engine
  • Rate limiting: 120 req/min per user

Frontend

  • Vue.js 2.7 Single Page Application
  • Vuex state management
  • Bootstrap Vue UI components
  • Axios HTTP (30s timeout)
  • Laravel Mix (webpack) build
  • HTML5 History mode routing

Warehouses

CodeNameLocation
MAINMain WarehouseCity Centre
NORTHNorth BranchNorthern District
SOUTHSouth BranchSouthern District
EASTEast DepotEastern Region

Integrations

  • VFD API (vfd.co.tz) — TRA tax receipts
  • SMS Gateway — Notifications
  • WhatsApp — Document sharing
  • Email SMTP — Automated emails

Installation & Setup

Follow these steps to install SmartVend on your server.

Requirements

ComponentVersionNotes
PHP8.1+BCMath, Ctype, JSON, Mbstring, OpenSSL, PDO, Tokenizer, XML
MySQL8.0+Or MariaDB 10.4+
Composer2.xPHP dependency manager
Web ServerNginx / ApachePoint document root to /public

Installation Steps

1

Upload Files

Extract the SmartVend package to your server (e.g. /var/www/smartvend) and install PHP dependencies:

composer install --optimize-autoloader --no-dev
2

Configure Environment

cp .env.example .env
php artisan key:generate

Edit .env — set DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD, APP_URL.

3

Database Setup

php artisan migrate
php artisan db:seed
php artisan passport:install
4

Finalize

php artisan storage:link
chmod -R 775 storage bootstrap/cache
php artisan config:cache && php artisan route:cache

Web-Based Setup Wizard

Access /setup in your browser after uploading the files for a guided installation without the command line.

1

Database Connection

Enter database host, port, name, username, and password. Use Test Connection to verify.

2

Application URL

Set APP_URL (e.g. https://yourdomain.com) and select environment.

3

Migrate & Seed

The wizard runs migrations, seeds, and passport install automatically.

4

Admin Account

Set name, email, and password for the initial Super Admin.

5

Done

The wizard writes .env, clears caches, and redirects to the login page.

Updating SmartVend

When a new version is available, a notification appears in the top bar. Apply it via /update in the browser, or via command line:

composer install --optimize-autoloader --no-dev
php artisan migrate
php artisan config:cache && php artisan route:cache && php artisan view:cache
Back up the database before applying any update — go to Backup & Maintenance → Generate Backup.

Login & Access

SmartVend uses OAuth2 token-based authentication via Laravel Passport. Every API call requires a Bearer token. The Vue.js frontend handles token storage and renewal automatically.

Login Page

Figure 1 — Login page

Default Admin Account

FieldValue
Emailadmin@example.com
Passwordpassword — change immediately
RoleSuper Admin (bypasses all permission checks)
Change the default password immediately after first login. Login is rate-limited to 5 attempts/minute.

How Authentication Works

1

User submits credentials

The login form sends the email and password to POST /api/getAccessToken along with the OAuth2 client credentials (client_id + client_secret from the oauth_clients table).

2

Server returns access token

Laravel Passport validates credentials and returns a Bearer token with a 1-year expiry. The token is stored in the browser's localStorage under access_token.

3

Token attached to every request

Axios is configured globally with Authorization: Bearer <token>. If the server returns 401, the frontend clears localStorage and redirects to the login page.

4

Permissions loaded on login

After token is obtained, the frontend fetches the user's profile and permissions. Navigation menus and action buttons are conditionally rendered based on what permissions the user holds.

Password Reset

Click "Forgot Password" Enter registered email Receive reset link via email Click link → Set new password
Password reset requires SMTP email to be configured in Settings → Mail Settings. Reset tokens expire after 60 minutes.

API Endpoints

MethodEndpointDescription
POST/api/password/createSend reset link to the provided email address
GET/api/password/find/{token}Validate a reset token before showing the form
POST/api/password/resetSet new password using a valid token
POST/api/logoutRevoke the current access token (server-side)

Account Security

FeatureDetails
Login rate limiting5 attempts per minute per IP. Exceeding this returns 429 Too Many Requests.
Is_Active checkEvery authenticated request checks that the user's is_active flag is 1. Deactivated users receive 403 immediately without touching any business logic.
Token revocationLogout calls POST /api/logout which deletes the token from oauth_access_tokens. Old tokens cannot be reused after logout.
Security headersAll responses include X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, and Referrer-Policy: strict-origin via the SecurityHeaders middleware.

Dashboard

Real-time business performance overview across all warehouses. The dashboard is the first screen after login and provides at-a-glance KPIs, trend charts, and alerts without running individual reports.

Dashboard

Figure 2 — Main dashboard

KPI Cards

The four KPI cards at the top of the dashboard summarise the current period's financial performance. They update whenever you change the date range filter.

WidgetHow It's CalculatedExample Value
Total SalesSum of all confirmed sale invoice grand totals for the selected periodTZS 4,850,000
Total PurchasesSum of all purchase invoice grand totals (goods received from suppliers)TZS 2,340,000
Total ExpensesSum of all approved expense records for the periodTZS 480,000
Total ProfitSales Total − Purchases Total − Expenses TotalTZS 2,030,000
Profit here is a gross approximation — it subtracts total purchases (not COGS). For an accurate net profit, use Reports → Profit & Loss which accounts for opening stock, closing stock, and period-specific COGS.

Charts & Visual Panels

PanelDescriptionInteraction
Sales & Purchases ChartDual line chart comparing daily sales revenue vs purchase costs over the selected periodHover to see exact values per day
Top Selling ProductsBar chart or ranked list of products by revenue in the period — shows which items drive the most incomeClick a product to open its detail page
Recent SalesLast 10 confirmed sales with client name, reference, total, and payment status badgeClick a row to open the sale
Payment Methods ChartDoughnut chart showing the split between cash, bank transfer, and other payment methodsHover segments for percentages
Low Stock AlertsList of products whose current stock is below the configured minimum reorder level at any warehouseClick to navigate to the product
Recent PurchasesLast 10 purchase invoices with supplier, reference, and payment statusClick a row to open the purchase

Filtering the Dashboard

Use the date range picker in the top-right of the dashboard to change the reporting period. All KPI cards and charts update simultaneously.

FilterEffect
Date Range (Start / End)Limits all KPIs and charts to transactions within the chosen dates
Warehouse FilterWhen set, restricts data to a single warehouse location (e.g. Main Warehouse only)
Default PeriodCurrent month — from the 1st of the month to today
The dashboard data is fetched via GET /api/dashboard_data with optional ?start_date=, ?end_date=, and ?warehouse_id= query parameters.

Low Stock Alerts Explained

The dashboard flags products that have fallen below their configured Minimum Alert quantity. This helps purchasing staff know what to reorder before stock runs out.

Example: Low Stock Panel
ProductWarehouseCurrent StockMin AlertStatus
Product ANORTH45 Kg50 KgLow
Product BSOUTH0 Kg20 KgOut of Stock

Navigate to Products → Stock Alerts or Reports → Low Stock for the full alert list with warehouse breakdown.

Products & Inventory

Manage your full product catalog, variants, barcodes, and real-time stock levels across all warehouse locations.

Products List

Products list — filterable by category, brand, warehouse, and stock status

Product Fields

FieldExample ValueNotes
Product NameBroiler Chicken (Dressed)Displayed on invoices and POS
Code / SKUCHK-001Unique identifier, auto-generated or manual
CategoryFresh PoultryHierarchical (parent → sub-category)
BrandInterchickOptional — used for filtering
Base UnitKgPrimary measurement unit
Sub-unitPiece = 1.8 KgAlternative selling unit with conversion factor
Cost PriceTZS 9,500 / KgUsed for profit calculation
Selling PriceTZS 12,500 / KgDefault retail price
Minimum Alert50 KgTriggers low-stock alert when below this level
Tax MethodInclusive / ExclusiveWhether price includes VAT or not
Barcode5901234123457EAN-13 or custom; scanned at POS
NoteKeep refrigeratedInternal product note

Product Variants

Variants allow one product to have multiple SKUs — e.g. Broiler Chicken sold in Small (under 1.5Kg), Medium (1.5–1.8Kg), and Large (over 1.8Kg) weight classes, each with its own barcode and price.

Example: Broiler Chicken Variants
VariantSKUBarcodePrice
Small (<1.5Kg)CHK-001-S5901234123457TZS 11,000/Kg
Medium (1.5–1.8Kg)CHK-001-M5901234123464TZS 12,500/Kg
Large (>1.8Kg)CHK-001-L5901234123471TZS 13,500/Kg

Promotional Offers

Set time-limited or quantity-based promotional prices. The POS automatically applies the offer price when conditions are met.

FieldExampleBehaviour
Offer PriceTZS 11,000 / KgApplied instead of standard selling price
Min Quantity10 KgOffer only activates above this quantity
Start Date2026-03-01Offer inactive before this date
End Date2026-03-31Offer expires after this date

Combo / Package Products

Bundle multiple products into a single sellable package. When a package is sold, each component's stock is decremented individually.

Example: Family Pack
ComponentQuantity
Broiler Chicken (Dressed)2 Kg
Chicken Wings0.5 Kg
Chicken Livers0.25 Kg

Stock Per Warehouse

Stock quantities are tracked independently per warehouse. The product detail page shows current quantity, reserved quantity, and the reorder level for each location.

WarehouseCurrent StockReservedAvailableReorder LevelStatus
MAIN320 Kg25 Kg295 Kg50 KgOK
NORTH45 Kg0 Kg45 Kg50 KgLow
SOUTH0 Kg0 Kg0 Kg30 KgOut of Stock

Barcodes & CSV Import

Barcode Labels

  • Generate EAN-13 or Code-128 barcodes per product
  • Print label sheets (multiple labels per page)
  • Labels include product name, price, and barcode — navigate to Products → Barcode

CSV Import — Column Reference

Upload a CSV or Excel file at Products → Import. Column headers are case-insensitive; common aliases are accepted (e.g. "SKU" for code, "Selling Price" for price).

ColumnRequiredExampleNotes
nameYesBroiler Chicken (Dressed)Product display name
codeYesSKU-0042Unique SKU / barcode value. Import fails if code already exists.
categoryYesPoultryCategory name — created automatically if it does not exist
costYes8000Purchase / cost price (numeric, no commas)
priceYes12500Selling price (numeric, no commas)
unitYesKgMust match an existing unit short name or full name in Catalog → Units
brandNoLocal FarmBrand name — created automatically if it does not exist. Leave blank or use "N/A" to skip.
stock_alertNo20Minimum quantity before low-stock alert fires. Defaults to 0.
noteNoKeep refrigeratedInternal product note
Import errors are reported per row — the rest of the rows still import successfully. Fix error rows and re-upload only the failed ones.

API Endpoints

MethodEndpointDescription
GET/api/productsList products (paginated, search, filter by category/brand/warehouse)
POST/api/productsCreate product
GET/api/products/{id}Product detail with all variants and stock
PUT/api/products/{id}Update product
DELETE/api/products/{id}Soft-delete product
GET/api/get_Products_by_warehouse/{warehouseId}Products with stock for a specific warehouse
GET/api/get_products_stock_alertsProducts below reorder level
GET/api/packagesList combo / package products
POST/api/products/import/csvBulk import from CSV
POST/api/products/delete/by_selectionBulk delete selected product IDs

Sales

Create and manage sales invoices, record multiple partial payments, send documents by email/SMS, and submit to VFD for TRA tax compliance.

Sales List

Sales list with search & date filter

Create Sale

Create sale form

Sale Workflow

Create Sale Add Products & Discounts Record Payment(s) Download / Email PDF Submit to VFD (TRA)

Sale Fields

FieldExampleNotes
ReferenceSL-MAIN-20260308-001Auto-generated: warehouse code + date + sequence
ClientCity Mart Traders LtdOptional — use walk-in customer for cash sales
WarehouseMain WarehouseStock deducted from this location
Date08 March 2026Sale date; defaults to today
Discount (%)5%Header-level discount on grand total
Tax18% VAT (inclusive)Configurable per product or header
ShippingTZS 5,000Optional delivery charge added to total
Payment MethodBank Transfer / Cash / ChequeLinked to an account in chart of accounts
NotesDeliver to cold storage B2Printed on invoice PDF

Example Sale

Sale: SL-MAIN-20260308-001
FieldValue
ReferenceSL-MAIN-20260308-001
ClientCity Mart Traders Ltd
WarehouseMain Warehouse
Date08 March 2026
ItemsBroiler Chicken (Dressed) × 25 Kg @ TZS 12,500 = TZS 312,500
Tax (18% VAT incl.)TZS 47,839
Grand TotalTZS 312,500
PaidTZS 200,000 (Bank Transfer — CRDB)
Balance DueTZS 112,500
Payment StatusPartial

Payment Statuses

StatusConditionAction Available
PaidTotal paid ≥ Grand TotalDownload PDF, Submit VFD
Partial0 < Paid < Grand TotalRecord additional payment
UnpaidNo payment recordedRecord first payment
Multiple payments can be recorded against a single sale. Each payment can use a different account/method (e.g. part cash, part bank transfer).

Sending Documents

ChannelWhat is SentAPI Endpoint
EmailPDF invoice attached to emailPOST /api/sales_send_email
SMSCustomizable SMS message with total and referencePOST /api/sales_send_sms
WhatsAppMessage with invoice linkPOST /api/sales_send_whatsapp

API Endpoints

MethodEndpointDescription
GET/api/salesList sales (paginated, search, filter by warehouse/date/status)
POST/api/salesCreate new sale with line items
GET/api/sales/{id}Full sale details with line items
PUT/api/sales/{id}Update sale
DELETE/api/sales/{id}Delete sale (soft-delete)
GET/api/get_payments_by_sale/{id}All payments recorded against a sale
GET/api/convert_to_sale_data/{quotationId}Load quotation data to pre-fill new sale form
GET/api/sale_pdf/{id}Download sale PDF
GET/api/sales_print_invoice/{id}Printable invoice view
GET/api/sales/{id}/preview-vfdPreview VFD receipt before submission
POST/api/sales/{id}/resubmit-vfdResubmit failed VFD receipt
POST/api/sales_delete_by_selectionBulk delete selected sale IDs

Point of Sale (POS)

Fast retail terminal designed for high-volume counter sales. Supports barcode scanning, split payment, draft orders, shift management, and automatic VFD receipt generation.

POS Terminal

POS terminal — product search, cart, and payment panel

POS Features

Product Entry

  • Barcode scanner — USB HID or device camera
  • Search by name, SKU, or barcode
  • Audible beep on successful scan
  • Offer / promo price auto-applied
  • Manual quantity and unit price override
  • Per-line discount

Payment & Receipts

  • Split payment: cash + bank transfer in one transaction
  • Cash change calculator with on-screen numpad
  • Customer selection for credit sales
  • VFD receipt auto-submitted on checkout
  • Thermal print receipt (A4 or 80mm roll)
  • Save draft and resume later

POS Transaction Workflow

Open Shift (enter float) Scan / Search Products Select Customer (optional) Enter Payment Checkout → VFD → Print Receipt
If Shift Requirement is enabled in Settings, cashiers must open a shift before making any POS sale. The system will block checkout if no active shift is found.

Shift Sessions

Shifts track a cashier's working session — the opening cash float, all sales made, and the closing cash count. A manager reviews and approves or rejects the session at end of day.

Shift StatusMeaningNext Action
ActiveShift is currently open; cashier can process salesEnd shift when done
Pending ApprovalCashier has ended the shift; manager review neededManager approves or rejects
ApprovedManager confirmed the closing figuresArchive / report
RejectedDiscrepancy found; cashier must explainInvestigate and resubmit
Example Shift — Main Warehouse Cashier
FieldValue
CashierJane Smith
WarehouseMain Warehouse
Open Time08:00 — 08 Mar 2026
Close Time17:00 — 08 Mar 2026
Opening FloatTZS 50,000
Total SalesTZS 284,500 (23 transactions)
Expected CashTZS 334,500
Counted CashTZS 332,000
Variance–TZS 2,500
StatusPending Approval

Draft Sales (Hold & Resume)

Save an in-progress cart as a draft to serve another customer. Drafts are stored per user and can be resumed at any time.

ActionEndpoint
Save current cart as draftPOST /api/pos/create_draft
List all saved draftsGET /api/get_draft_sales
Load draft into POSGET /api/pos/data_draft_convert_sale/{id}
Submit draft as final salePOST /api/pos/submit_sale_from_draft
Delete a draftDELETE /api/remove_draft_sale/{id}

API Endpoints

MethodEndpointDescription
POST/api/pos/create_posComplete a POS checkout transaction
GET/api/pos/get_products_posProducts available at active shift warehouse
GET/api/pos/data_create_posPOS setup data: settings, accounts, customers
GET/api/shift-sessions/currentGet current active shift for the logged-in user
POST/api/shift-sessions/startOpen a new shift (cashier enters opening float)
POST/api/shift-sessions/endClose the current shift (enter closing cash count)
POST/api/shift-sessions/approveManager approves a closed shift
POST/api/shift-sessions/rejectManager rejects a closed shift

Purchases

Record supplier invoices, track payments, manage purchase returns, and import bulk purchases via CSV.

Purchases

Purchases list

Purchase Orders

Purchase orders list

Purchase vs Purchase Order

DocumentPurposeUpdates Stock?
Purchase Invoice (Purchases menu)Financial record of goods bought from supplier — creates an accounts payable entryNo — stock updated via GRN approval
Purchase Order (PO & GRN menu)Formal order sent to supplier before receiving goodsNo
GRN (Goods Received Note)Records physical receipt of goods at a warehouseYes — on approval

Purchase Invoice Fields

FieldExampleNotes
ReferencePR_1042Auto-generated or manual supplier invoice number
SupplierPrime Distributors LtdMust exist in Providers list
WarehouseMAINDestination for this purchase
Date08 March 2026Invoice date from supplier
Tax18% VAT (exclusive)Configurable per purchase
Discount2%Supplier discount applied to total
ShippingTZS 15,000Freight / delivery charge
Payment MethodBank TransferAccount debited on full payment

Example Purchase Invoice

Purchase: PR_1042
FieldValue
ReferencePR_1042
SupplierPrime Distributors Ltd
GRN LinkedGRN-000014
ItemLive Broilers × 200 birds @ TZS 8,000 = TZS 1,600,000
Tax (18% excl.)TZS 288,000
Grand TotalTZS 1,888,000
PaidTZS 1,000,000
BalanceTZS 888,000
StatusPartial

Purchase Returns

Return defective or over-delivered goods to the supplier. A purchase return reduces the amount owed to the supplier and (if approved) reverses the stock increase from the original purchase.

Select Original Purchase Choose Items & Qty Manager Approves Stock Reversed Claim Refund / Credit

API Endpoints

MethodEndpointDescription
GET/api/purchasesList purchases (paginated)
POST/api/purchasesCreate purchase invoice (optionally linked to GRN via grn_id)
GET/api/purchases/{id}Purchase details with line items
PUT/api/purchases/{id}Update purchase
DELETE/api/purchases/{id}Delete purchase
GET/api/get_payments_by_purchase/{id}All payments made against a purchase
GET/api/purchase_pdf/{id}Download purchase PDF
GET/api/returns/purchaseList purchase returns
POST/api/returns/purchaseCreate purchase return
POST/api/returns/purchase/approve/{id}Approve purchase return (reverses stock)

Clients & Providers

Manage your customer database and supplier directory. Each contact holds full transaction history, outstanding balance, and communication preferences.

Clients

Clients list — searchable with outstanding balance displayed

Client Fields

FieldExampleNotes
NameCity Mart Traders LtdCompany or individual name
Phone+000 712 345 678Used for SMS notifications
Emailorders@citymart.comUsed for invoice email sending
AddressCity CentrePrinted on invoices
CityDar es Salaam
TINTAX-123-456-789Taxpayer ID; included on VFD receipt
Credit LimitTZS 5,000,000Maximum credit allowed before payment required
Opening BalanceTZS 0Historical balance owed at system go-live

Client Statement

The client statement shows all transactions (sales, payments, returns) for a client over a date range, with running balance. Available as PDF download.

Client: City Mart Traders Ltd
DateTypeReferenceDebitCreditBalance
2026-03-01SaleSL-MAIN-20260301-002TZS 150,000TZS 150,000
2026-03-05PaymentPAY-SL-2026-0078TZS 100,000TZS 50,000
2026-03-08SaleSL-MAIN-20260308-001TZS 312,500TZS 362,500
2026-03-08PaymentPAY-SL-2026-0085TZS 200,000TZS 162,500

Providers (Suppliers)

Provider Fields

FieldExampleNotes
NamePrime Distributors LtdCompany or trading name
Phone+000 712 345 678Primary contact number
Emailorders@primedist.comUsed for purchase order emails
AddressIndustrial Zone, Block 4Printed on purchase orders
CityCity Centre
TINTAX-987-654-321Supplier taxpayer ID for tax records
Opening Balance0Historical balance owed at system go-live

Supplier Statement

Supplier: Prime Distributors Ltd
DateTypeReferenceDebitCreditBalance
2026-03-01PurchasePR_1038920,000920,000
2026-03-05PaymentPAY-PR-2026-0041500,000420,000
2026-03-08PurchasePR_10421,888,0002,308,000
2026-03-08PaymentPAY-PR-2026-00471,000,0001,308,000

API Endpoints

Clients

MethodEndpointDescription
GET/api/clientsList clients (paginated)
POST/api/clientsCreate client
PUT/api/clients/{id}Update client
DELETE/api/clients/{id}Delete client
GET/api/get_clients_without_paginateAll clients as flat list (for dropdowns)
GET/api/get_client_store_data/{id}Client summary with outstanding balance and recent transactions
POST/api/clients_pay_dueRecord a payment for a client's outstanding balance
POST/api/clients/import/csvBulk import clients from CSV

Providers

MethodEndpointDescription
GET/api/providersList suppliers (paginated)
POST/api/providersCreate supplier
PUT/api/providers/{id}Update supplier details
DELETE/api/providers/{id}Delete supplier
GET/api/get_providers_without_paginateAll suppliers as flat list (for dropdowns)
GET/api/get_provider_store_data/{id}Supplier summary with outstanding payable and recent purchases
POST/api/pay_supplier_dueRecord payment for supplier outstanding balance
POST/api/providers/import/csvBulk import suppliers from CSV

Payments

Record all incoming and outgoing financial payments. Each payment is linked to a document (sale, purchase, return) and an account in the chart of accounts.

Payment Types

TypeDirectionLinked ToAccount Effect
Sale PaymentIncomingSale invoiceDR cash/bank account, CR Accounts Receivable
Purchase PaymentOutgoingPurchase invoiceDR Accounts Payable, CR cash/bank account
PO PaymentOutgoingPurchase Order (advance)DR prepayment account, CR cash/bank account
Sale Return PaymentOutgoingSale returnRefund issued from cash/bank account
Purchase Return PaymentIncomingPurchase returnSupplier credit received into cash/bank account

Example Sale Payment

Payment: PAY-SL-2026-0085
FieldValue
ReferencePAY-SL-2026-0085
SaleSL-MAIN-20260308-001
ClientCity Mart Traders Ltd
AmountTZS 200,000
Payment MethodBank Transfer
AccountCRDB Bank Account (112000)
Date08 March 2026
NotesPart payment — TZS 112,500 remaining

API Endpoints

MethodEndpointDescription
GET/api/payment_saleList all sale payments
POST/api/payment_saleRecord a sale payment
PUT/api/payment_sale/{id}Update a sale payment
DELETE/api/payment_sale/{id}Delete sale payment (reverses balance)
GET/api/payment_sale_get_numberGet next auto-generated payment reference
GET/api/payment_purchaseList all purchase payments
POST/api/payment_purchaseRecord a supplier payment
GET/api/payment_purchase_orderList all PO advance payments
POST/api/payment_purchase_orderRecord PO advance payment
GET/api/payment/returns_saleList sale return refund payments
GET/api/payment/returns_purchaseList purchase return receipt payments
GET/api/payment_sale_pdf/{id}Download payment receipt PDF

Expenses & Deposits

Record and track all operational costs (expenses) and cash lodgments (deposits). Both modules update account balances and appear in financial reports.

Expenses

Expenses list — searchable by category, date, and warehouse

Accounts

Chart of accounts — balance updated on each transaction

Expenses

Outgoing

An expense records money spent on operational costs — fuel, utilities, salaries, maintenance, etc. Each expense is categorised, linked to a paying account, and optionally assigned to a warehouse (branch).

Expense Fields

FieldExampleNotes
ReferenceEXP-2026-0023Auto-generated sequential number
CategoryFuel & TransportOrganises expenses for reporting. Manage categories via Expenses → Categories
DescriptionDelivery vehicle fuel — City to RegionAppears on printed expense vouchers
AmountTZS 85,000Full amount paid out
AccountPetty Cash (111000)The account from which this expense is paid
WarehouseMain WarehouseBranch incurring the cost (for per-branch expense reports)
Date08 March 2026Date the expense was incurred
NoteSupplier receipt attachedInternal note, not printed

Expense Workflow

Create Expense Manager Approves Account Balance Deducted Appears in Expense Reports
Expense categories can be added or renamed under Expenses → Categories. Common examples: Salaries, Utilities, Rent, Fuel & Transport, Marketing, Miscellaneous.

Example Expense Record

Expense: EXP-2026-0023
FieldValue
ReferenceEXP-2026-0023
CategoryFuel & Transport
DescriptionDelivery vehicle fuel — City to Region route
AmountTZS 85,000
AccountPetty Cash (111000)
WarehouseMain Warehouse
Date08 March 2026
StatusApproved — Petty Cash reduced by TZS 85,000

API Endpoints

MethodEndpointDescription
GET/api/expensesList expenses (paginated, filter by category/date/warehouse)
POST/api/expensesCreate new expense
PUT/api/expenses/{id}Edit an existing expense
DELETE/api/expenses/{id}Delete expense (reverses account balance)
POST/api/expenses/approve/{id}Approve expense — deducts from the linked account
POST/api/expenses/delete/by_selectionBulk delete selected expense IDs
GET/api/expenses_categoryList expense categories
POST/api/expenses_categoryCreate expense category

Deposits

Incoming

A deposit records money received by the business that is not a sale payment — for example, a cash advance from an investor, a bank loan drawdown, or a customer pre-payment. The deposit increases the selected account balance and is recorded as a liability (Customer Deposits) in the double-entry ledger.

Deposit Fields

FieldExampleNotes
ReferenceDEP-2026-0018Auto-generated
DescriptionAdvance from ABC InvestorBrief description of the deposit source
AmountTZS 2,000,000Deposited amount (positive)
AccountCRDB Bank Account (112000)Account receiving the deposit
Date08 March 2026Date money was received

Example Deposit Record

Deposit: DEP-2026-0018
FieldValue
ReferenceDEP-2026-0018
DescriptionInitial operating capital from head office
AmountTZS 5,000,000
AccountCRDB Bank Account (112000)
Date08 March 2026

API Endpoints

MethodEndpointDescription
GET/api/depositsList all deposits (paginated)
POST/api/depositsCreate deposit — increases the linked account balance
PUT/api/deposits/{id}Edit deposit amount or details
DELETE/api/deposits/{id}Delete deposit — reverses the balance increase
GET/api/deposits_categoryList deposit categories
POST/api/deposits_categoryCreate deposit category
PUT/api/deposits_category/{id}Rename deposit category
DELETE/api/deposits_category/{id}Delete deposit category

Accounts & Accounting

SmartVend uses full double-entry bookkeeping. Every financial transaction automatically creates a journal entry with matching debit and credit lines — ensuring the ledger is always balanced and auditable.

What Is Double-Entry Accounting?

Double-entry accounting means that every transaction affects at least two accounts — one is debited and another is credited by the same amount. This ensures the accounting equation always holds:

Assets = Liabilities + Equity

For example, when a customer pays TZS 200,000 for a sale:

AccountEffectAmountWhy
CRDB Bank Account (112000)DRTZS 200,000Money enters the bank — asset increases
Accounts Receivable (113000)CRTZS 200,000Customer's debt is cleared — receivable decreases
In SmartVend, journal entries are created automatically by AccountingService.php. You do not need to manually enter them. Each entry is linked to the source document (sale, expense, GRN, etc.) for easy tracing.

Chart of Accounts

All financial accounts are maintained in a hierarchical chart of accounts. Navigate to Accounts → Chart of Accounts to view balances, add new accounts, and inspect transaction history per account.

CodeAccount NameTypeNormal BalanceExample Balance
111000Petty CashAssetDebitTZS 234,500
112000CRDB Bank AccountAssetDebitTZS 8,450,000
113000Accounts ReceivableAssetDebitTZS 1,320,750
200000Liabilities (parent)LiabilityCredit
211000Accounts PayableLiabilityCreditTZS 2,100,000
212000Customer DepositsLiabilityCreditTZS 450,000
410000Sales RevenueRevenueCreditTZS 48,500,000
430000Sales ReturnsRevenue (contra)DebitTZS 1,200,000
500000Expenses (parent)ExpenseDebit
511000Cost of Goods SoldExpenseDebitTZS 23,400,000
512000Purchase ReturnsExpense (contra)CreditTZS 380,000
520000General ExpensesExpenseDebitTZS 2,840,000
You can add custom accounts at Accounts → Add Account. Specify the parent account, type (asset/liability/revenue/expense), and normal balance direction. Custom cash or bank accounts become selectable in payment forms.

Automatic Journal Entries

The following table shows which journal entries are created automatically for each type of transaction. You can view them via Accounts → Journal Entries.

TransactionDebitCredit
Sale recordedAccounts Receivable (113000)Sales Revenue (410000)
Sale payment receivedCash/Bank account (chosen by user)Accounts Receivable (113000)
Purchase invoiceCost of Goods Sold (511000)Accounts Payable (211000)
Supplier payment madeAccounts Payable (211000)Cash/Bank account (chosen by user)
Expense approvedGeneral Expenses (520000)Cash/Bank account (paid from)
Deposit recordedCash/Bank account (received into)Customer Deposits (212000)
GRN approvedInventory / Stock accountGoods Received Not Invoiced
Stock adjustment (add)Inventory / Stock accountAdjustment account
Sale return approvedSales Returns (430000)Inventory / Stock account

API Endpoints

MethodEndpointDescription
GET/api/accountsList all accounts with current balances
POST/api/accountsCreate a new account (specify parent, type, normal_balance)
PUT/api/accounts/{id}Rename or re-parent an account
DELETE/api/accounts/{id}Delete an account (only if balance is zero and no transactions)
GET/api/accounts/{id}/journal-entriesAll journal entries for a specific account
GET/api/transfer_moneyList account-to-account internal transfers
POST/api/transfer_moneyTransfer balance between two accounts (e.g. bank → petty cash)

Returns

SmartVend handles both sale returns (customers returning goods) and purchase returns (sending goods back to suppliers). All returns require manager approval before stock quantities and financial accounts are updated, providing a controlled audit trail.

Sale Returns — Customer Returns Goods

A sale return is raised when a customer brings back goods — damaged items, incorrect quantities, quality issues, or order mistakes. The return reverses part of the original sale, restores stock, and records a refund to the customer.

Select Original Sale Choose Items & Qty to Return Enter Return Reason Manager Approves Stock Restored to Warehouse Refund Payment Recorded
After approval, the original sale's payment status may change from Paid back to Partial if a refund is issued. Navigate to Finance → Sale Returns to record the refund payment against the return.

Sale Return Fields

FieldExampleNotes
ReferenceSR-2026-0008Auto-generated
Original SaleSL-MAIN-20260308-001Must exist in the system
WarehouseMAINStock is restored to the original sale's warehouse
Returned ItemsBroiler Chicken × 5 KgCan be a partial return — not all items need to be returned
Return ReasonQuality issue — underweight birdsPrinted on the credit note PDF
StatusPending → ApprovedOnly approved returns affect stock and finances
Example Sale Return
FieldValue
Return RefSR-2026-0008
Original SaleSL-MAIN-20260308-001
ClientCity Mart Traders Ltd
Item ReturnedBroiler Chicken (Dressed) × 5 Kg @ TZS 12,500
Return ValueTZS 62,500
ReasonQuality issue — underweight birds
StatusApproved
RefundTZS 62,500 recorded as Sale Return Payment — Petty Cash

Purchase Returns — Return Goods to Supplier

A purchase return is raised when goods received from a supplier need to be sent back — due to defects, over-delivery, or specification mismatch. The return reduces the amount owed to the supplier and (on approval) removes the stock from the warehouse.

Select Original Purchase Specify Returned Qty & Reason Manager Approves Stock Deducted from Warehouse Accounts Payable Reduced Claim Refund / Credit Note
Once approved, the outstanding payable to the supplier is reduced by the return value. If the supplier issues a cash refund instead of a credit note, record a Purchase Return Payment to log the incoming amount into your account.
Example Purchase Return
FieldValue
Return RefPR-RET-2026-0003
Original PurchasePR_1042 — Prime Distributors Ltd
Item ReturnedLive Broilers × 20 birds @ TZS 8,000 = TZS 160,000
ReasonDiseased birds identified during slaughter QC
StatusApproved — Main Warehouse stock reduced by 20 birds, supplier payable reduced by 160,000

API Endpoints

Sale Returns

MethodEndpointDescription
GET/api/returns/saleList all sale returns (paginated, filter by date/warehouse)
POST/api/returns/saleCreate a sale return (status: pending, no stock effect yet)
GET/api/returns/sale/{id}Full sale return details with line items
POST/api/returns/sale/approve/{id}Approve — restores stock to warehouse and updates finances
DELETE/api/returns/sale/{id}Delete unapproved return
GET/api/return_sale_pdf/{id}Download credit note PDF for the sale return
GET/api/returns/sale/payment/{id}Refund payments recorded against a specific sale return
POST/api/payment/returns_saleRecord a refund payment for a sale return

Purchase Returns

MethodEndpointDescription
GET/api/returns/purchaseList all purchase returns
POST/api/returns/purchaseCreate a purchase return
POST/api/returns/purchase/approve/{id}Approve — deducts stock and reduces accounts payable
DELETE/api/returns/purchase/{id}Delete unapproved return
POST/api/payment/returns_purchaseRecord cash received from supplier as purchase return refund

Warehouses

Warehouses are the core organisational unit in SmartVend. Every stock movement, sale, purchase, transfer, and adjustment is linked to a specific warehouse. You can create as many warehouses as you need — one store, ten branches, a van fleet — and remove or rename them at any time. Users can be restricted to specific warehouses via their role permissions.

Warehouses

Figure 6 — Warehouses management

Warehouse Fields

FieldExampleNotes
NameMain WarehouseFull name displayed in forms, reports, and documents
CodeMAINMax 10 chars, uppercase. Used in sale reference numbers (e.g. SL-MAIN-20260308-001). Cannot be changed after sales are recorded.
Emailmain@yourbusiness.comPrinted on sale and purchase documents as the branch contact
Phone+000 100 200 300Printed on documents and used for SMS notifications
Address123 Industrial Avenue, City CentrePhysical address printed on documents
CityCity CentreCity shown in the warehouse list
VFD ActivatedYes / NoWhen enabled, POS sales at this branch automatically submit to TRA VFD. Toggle separately per branch.

Example Warehouse Setup

SmartVend supports any number of warehouses — from a single location to dozens of branches, depots, and vans. The examples below illustrate a typical multi-branch setup. Your actual warehouses are configured under Settings → Warehouses and can be added or removed at any time.
CodeNameLocationVFDNotes
MAINMain WarehouseCity CentreActiveCentral hub — receiving, wholesale dispatch, finance
NORTHNorth BranchNorthern DistrictActiveRetail outlet — walk-in and local B2B
SOUTHSouth BranchSouthern DistrictActiveRetail counter — restocked weekly from MAIN
EASTEast DepotEastern RegionActiveRegional depot — serves upcountry wholesale
VAN01Delivery Van 1MobileOffExample of a mobile stock location (van, kiosk)

The codes above (MAIN, NORTH, SOUTH, EAST, VAN01) are illustrative only. Use any code and name that matches your real locations.

Example Warehouse Record

Sample warehouse — adapt to your own location details
FieldExample Value
NameMain Warehouse
CodeMAIN
Address123 Industrial Avenue, City Centre
Emailmain@yourbusiness.com
Phone+000 100 200 300
VFD ActiveYes

How Warehouses Affect Stock

  • Sales — deduct stock from the selected warehouse. A sale at Main Warehouse reduces Main Warehouse stock only.
  • Purchases / GRN — add stock to the destination warehouse on GRN approval.
  • Transfers — move stock between warehouses. Source is reduced when dispatched; destination is increased when received.
  • Adjustments — increase or decrease stock at the specified warehouse on manager approval.
  • POS — POS terminal uses the warehouse linked to the cashier's active shift session.
  • Reports — all reports can be filtered by warehouse to compare branch performance.
Warehouse codes are embedded in sale reference numbers. Once a sale is recorded, the code cannot be changed without affecting all historical references.

API Endpoints

MethodEndpointDescription
GET/api/warehousesList all warehouses
POST/api/warehousesCreate a new warehouse
PUT/api/warehouses/{id}Update warehouse details
DELETE/api/warehouses/{id}Delete warehouse (only if no stock or transactions linked)
PUT/api/vfd_switch_activated/{id}Toggle VFD tax submission on/off for a specific warehouse
GET/api/get_Products_by_warehouse/{id}All products with their stock level at the given warehouse
GET/api/report/warehouse_reportFull sales, purchases, and expense summary per warehouse

Stock Transfers

Move stock between warehouse locations with a multi-step workflow: create, submit, approve, dispatch, and receive confirmation at the destination.

Transfers

Stock transfers list — showing status and warehouse routes

Transfer Workflow

Create Transfer Submit for Approval Manager Approves Goods Dispatched Destination Confirms Receipt Stock Updated Both Ends
Stock is deducted from the source warehouse when the transfer is approved and dispatched. It is added to the destination only when the receiving warehouse confirms receipt.

Transfer Statuses

StatusMeaningStock Effect
DraftCreated, not yet submittedNone
PendingSubmitted, awaiting approvalNone
ApprovedApproved, ready to dispatchNone
SentGoods dispatched from sourceSource warehouse deducted
CompletedDestination confirmed receiptDestination warehouse added

Example Transfer

Transfer: TR-2026-0019
FieldValue
ReferenceTR-2026-0019
FromMain Warehouse
ToEast Depot
ProductBroiler Chicken (Dressed) × 80 Kg
Transfer Date08 March 2026
StatusSent — awaiting East Depot confirmation

Transfer Requests

A transfer request allows a destination warehouse to formally request stock from another location. The source warehouse can approve or reject the request before creating the actual transfer.

Destination Requests Stock Source Reviews Approves → Creates Transfer

API Endpoints

MethodEndpointDescription
GET/api/transfersList all transfers
POST/api/transfersCreate transfer
POST/api/transfer/approve/{id}Manager approves transfer
POST/api/transfer/submit/{id}Mark goods as dispatched
POST/api/transfer/complete/{id}Destination confirms receipt — updates destination stock
GET/api/receivesList transfer receives at destination
POST/api/receive/approve/{id}Approve received transfer
GET/api/requestsList transfer requests
POST/api/request/approve/{id}Approve transfer request

Quotations

Create price quotations for customers and convert accepted ones to sales with a single click. Send by email, SMS, or WhatsApp.

Quotations

Quotations list — with status filters and conversion action

Quotation Workflow

Create Quotation Send to Client (Email/SMS) Client Accepts Convert to Sale

Quotation Fields

FieldExampleNotes
ReferenceQT-2026-0034Auto-generated sequential number
ClientGrand Hospitality GroupOptional — leave blank for anonymous prospect
WarehouseMain WarehouseStock availability checked against this location
Date08 March 2026Date the quotation is issued
Valid Until15 March 2026Expiry date shown on printed quotation PDF
Discount (%)5%Header-level discount applied to grand total
Tax18% exclusiveConfigurable per quotation; carried over to sale on conversion
Shipping5,000Optional delivery charge included in total
NotesPrices valid for 7 days onlyPrinted on the quotation PDF
StatusDraft → Sent → Converted / ExpiredUpdated automatically when sent or converted

Quotation Statuses

StatusMeaningAction Available
DraftQuotation created but not yet sent to the clientEdit, send by email/SMS, delete
SentQuotation delivered to client — awaiting responseFollow up, convert to sale, expire
ConvertedClient accepted — sale invoice created from this quotationView linked sale, download PDF
ExpiredValid-until date has passed without conversionDuplicate with new dates, download PDF

Example Quotation

Quotation: QT-2026-0034
FieldValue
ReferenceQT-2026-0034
ClientGrand Hospitality Group
WarehouseMain Warehouse
ItemProduct A × 200 units @ 12,500 = 2,500,000
Tax (18% excl.)450,000
Grand Total2,950,000
Valid Until15 March 2026
StatusSent — awaiting client confirmation
When converting to a sale, all line items, pricing, client, and warehouse are pre-filled. You can adjust quantities or pricing before confirming the final sale.

Sending a Quotation

After saving a quotation, use the action buttons on the quotation detail page to deliver it to your client. The quotation PDF is generated automatically.

ChannelWhat Is SentAPI Endpoint
EmailPDF quotation attached; subject and body use the email template from Settings → NotificationsPOST /api/quotation_send_email
SMSShort message with reference, total, and valid-until date; client's phone number from their profilePOST /api/quotation_send_sms
WhatsAppMessage with a link to download the quotation PDFPOST /api/quotation_send_whatsapp

API Endpoints

MethodEndpointDescription
GET/api/quotationsList quotations (paginated, filter by date/client/warehouse/status)
POST/api/quotationsCreate a new quotation with line items
GET/api/quotations/{id}Full quotation details with all line items
PUT/api/quotations/{id}Edit a quotation (only while in Draft or Sent status)
DELETE/api/quotations/{id}Delete a quotation (soft-delete)
GET/api/quote_pdf/{id}Download quotation as a PDF document
GET/api/convert_to_sale_data/{id}Return quotation data pre-formatted to fill the new sale form
POST/api/quotation_send_emailEmail quotation PDF to the client
POST/api/quotation_send_smsSend quotation SMS to client phone

Purchase Orders & GRN

SmartVend offers flexible procurement — formal Purchase Orders (PO) for planned procurement, or Direct GRNs for immediate receiving. The GRN (Goods Received Note) is the document that actually updates warehouse stock when goods are physically received.

Purchase Orders

Purchase orders list — showing PO status and supplier

GRN List

Goods Received Notes (GRN) list — each line shows linked PO and approval status

Three Receiving Workflows

WorkflowWhen to UseSteps
PO → GRN → Purchase Planned procurement with formal approval before goods arrive. Ensures purchasing is authorized before any stock or financial commitment. Create PO → Submit for approval → Manager approves PO → Goods arrive → Create GRN (linked to PO) → Approve GRN (stock updated) → Convert to Purchase Invoice
Direct GRN → Purchase Goods arrive unexpectedly without a prior purchase order (walk-in supplier, emergency restock) Navigate to PO & GRN → Receive Goods → Enable Direct GRN toggle → Select warehouse & supplier → Add products → Approve GRN → Convert to Purchase Invoice
Direct Purchase Invoice Skip the receiving workflow entirely — useful for service purchases or when stock has already been counted Go to Purchases → Create Purchase → Fill supplier, items, amounts → Save
Only the GRN approval updates warehouse stock. Creating a Purchase Invoice alone does NOT add stock. Use the PO → GRN workflow or Direct GRN for any goods that need to appear in inventory.

Purchase Order Fields

FieldExampleNotes
PO ReferencePO-2026-0055Auto-generated
SupplierPrime Distributors LtdMust exist in Providers list
WarehouseMAINDestination warehouse for the ordered goods
Expected Date10 March 2026When goods are expected — for planning only
Products & QuantitiesLive Broilers × 500 birdsQuantities and unit prices from negotiated terms
Tax18% VAT exclusiveConfigurable per order
NotesPriority delivery — cold chain requiredPrinted on PO document sent to supplier

PO Status Flow

Draft Created Pending Submitted Approved Received GRN created Completed

GRN — Goods Received Note

The GRN is the physical receiving document. It records what was actually received at the warehouse — which may differ from the PO quantity (partial delivery, damaged items, etc.). Only on GRN approval does the stock quantity in the system increase.

Create GRN

GRN creation form — toggle Direct GRN to receive without a linked PO

GRN Fields

FieldExampleNotes
ReferenceGRN-000014Auto-generated sequential number
Purchase OrderPO-2026-0055 or NoneLeave blank for Direct GRN
SupplierPrime Distributors LtdAuto-filled from PO, or choose manually for Direct GRN
WarehouseMain WarehouseWhere the goods are being received
Received Date08 March 2026Physical delivery date
Products & QuantitiesLive Broilers × 200 birdsActual quantities counted on receipt — may differ from PO
QC StatusPassed / FailedQuality check result — for record keeping
Notes15 birds rejected — disease symptomsInternal notes on receiving condition
Example GRN (Direct — no prior PO)
FieldValue
ReferenceGRN-000014
Purchase OrderNone (Direct GRN)
SupplierPrime Distributors Ltd
WarehouseMain Warehouse
Received Qty200 birds
QC StatusPassed
StatusApproved → Main Warehouse stock +200 birds → converted to PR_1042
After GRN approval, click Convert to Purchase Invoice on the GRN detail page to auto-fill a purchase invoice form with the supplier, warehouse, and received quantities. The GRN is then marked Completed and linked to the purchase for traceability.

Supplier Claims

A supplier claim is raised when goods received from a supplier do not meet the agreed specification — wrong quantity, quality failure, or pricing discrepancy. Claims are logged against the original purchase order and tracked through an approval workflow before any credit is applied.

Identify Discrepancy on GRN Create Claim (linked to PO) Send to Supplier Manager Approves Claim Supplier Issues Credit / Replacement

Claim Fields

FieldExampleNotes
ReferenceCLM-2026-0004Auto-generated
Purchase OrderPO-2026-0055The PO against which the claim is raised
SupplierPrime Distributors LtdAuto-filled from the linked PO
Claim TypeQuality / Quantity / PricingCategorises the nature of the dispute
ProductsLive Broilers × 30 birdsLine items subject to the claim
Claim Amount240,000Value being disputed or reclaimed from supplier
Description30 birds delivered underweight — avg 1.2 Kg vs contracted 1.8 KgEvidence details for the supplier
StatusPending → Approved / RejectedManager must approve before supplier is notified
Example Supplier Claim
FieldValue
ReferenceCLM-2026-0004
POPO-2026-0055 — Prime Distributors Ltd
ItemLive Broilers × 30 birds
Claim Amount240,000 (30 birds × 8,000)
ReasonUnderweight delivery — agreed 1.8 Kg/bird, received 1.2 Kg/bird average
StatusApproved — supplier to issue credit note or replacement delivery

Claim API Endpoints

MethodEndpointDescription
GET/api/claimsList all supplier claims
POST/api/claimsCreate a new claim (linked to a purchase order)
GET/api/claims/{id}Claim details with line items
POST/api/claims/approve/{id}Manager approves the claim

API Endpoints

Purchase Orders

MethodEndpointDescription
GET/api/purchase_ordersList all purchase orders (paginated)
POST/api/purchase_ordersCreate a new purchase order
GET/api/purchase_orders/{id}PO details with all line items
PUT/api/purchase_orders/{id}Edit PO before approval
DELETE/api/purchase_orders/{id}Delete unapproved PO
POST/api/purchase_order/submit/{id}Submit PO for approval
POST/api/purchase_order/approve/{id}Manager approves PO — enables GRN creation
GET/api/purchase_pdf/{id}Download PO as PDF to send to supplier

Goods Received Notes (GRN)

MethodEndpointDescription
GET/api/grnsList all GRNs (paginated)
POST/api/grn/createCreate GRN — set order_id=null for Direct GRN
GET/api/grn/{id}GRN details with line items
PUT/api/grn/{id}Edit GRN before approval
POST/api/grn/approve/{id}Approve GRN — updates warehouse stock and creates journal entry
GET/api/get_receive_data/{grnId}Pre-fill purchase invoice form from an approved GRN
GET/api/get_orderPOs, suppliers, and warehouses for the GRN creation form

Stock Adjustments

Manually correct stock quantities when the physical count differs from the system quantity — for write-offs, spoilage, theft, damage, or found stock. Every approved adjustment generates a double-entry journal entry to maintain ledger integrity.

Adjustments

Figure 9 — Stock adjustments list with status and warehouse filter

Adjustment Types

TypeEffect on StockUse CaseExample
Addition (+)Increases warehouse stock quantityFound stock during a physical count, unreported receipt+12 Kg Broiler Chicken found in cold store during month-end count
Subtraction (–)Decreases warehouse stock quantitySpoilage, theft, damage, expiry write-off–8 Kg Chicken livers spoiled due to refrigeration failure

Adjustment Workflow

Create Adjustment Select Warehouse & Products Enter Qty & Type (+/–) Add Reason / Note Manager Approves Stock & Journal Updated
Stock is not updated until a manager approves the adjustment. Draft adjustments have no effect on inventory levels or financial accounts.

Adjustment Fields

FieldExampleNotes
ReferenceADJ-2026-0011Auto-generated
Date08 March 2026Date of the physical event
WarehouseMain WarehouseOnly the selected warehouse is affected
Product(s)Broiler Chicken (Dressed)Multiple products can be adjusted in one document
Quantity8 KgThe magnitude of the change (always positive; direction set by Type)
TypeSubtraction (–)Addition or Subtraction
Reason / NoteSpoilage due to power outagePrinted on the adjustment document for audit purposes

Example Adjustment

Adjustment: ADJ-2026-0011
FieldValue
ReferenceADJ-2026-0011
WarehouseNorth Branch
Date08 March 2026
ProductChicken Wings
Quantity15 Kg
TypeSubtraction
ReasonFreezer malfunction — product spoiled overnight
StatusApproved — North Branch stock reduced by 15 Kg, journal entry DR General Expenses / CR Inventory

API Endpoints

MethodEndpointDescription
GET/api/adjustmentsList all adjustments (paginated, filter by warehouse/date)
POST/api/adjustmentsCreate a new stock adjustment (status: pending)
GET/api/adjustments/{id}Full adjustment details with all product lines
PUT/api/adjustments/{id}Edit adjustment before approval
DELETE/api/adjustments/{id}Delete unapproved adjustment
POST/api/adjustments/approve/{id}Approve — updates stock quantities and creates journal entry

VFD / TRA Tax Compliance

SmartVend integrates with the VFD API to submit tax receipts to the Tanzania Revenue Authority (TRA) in real time.

VFD Receipts

VFD receipts list

VFD Z-Report

Daily Z-Report

Environments

EnvironmentVFD API URLTRA Verify URL
Staging / Testhttps://test.myvfd.apphttps://virtual.tra.go.tz/efdmsRctVerify/
Live / Productionhttps://vfd.co.tzhttps://verify.tra.go.tz/

VFD Configuration (Settings → VFD Tab)

VFD Settings

VFD settings tab — token is write-only (never displayed after saving)

Example VFD Config
FieldExample ValueNotes
EnvironmentLiveSwitch to Test for staging
API Token••••••••Write-only — enter new value to replace
TINTAX-987654321Taxpayer Identification Number
VRNVAT-001234-LVAT Registration Number (optional)
Serial Number10TZ100006Device serial from TRA
UINXXXXXXXXUnit Identification Number
Tax OfficeIlala Tax Region
Invoice Color#17549CAccent color on printed receipts
Security: The API token is never returned to the browser after saving. The settings page shows only a status indicator ("token saved"). Enter a new token only when rotating credentials.
External VFD API errors (401, 403, 5xx) are mapped to 502 Bad Gateway to protect internal details. POS receipts automatically hide TIN, VRN, Serial, and UIN fields when not configured.

Z-Report

The daily Z-Report summarises all VFD-submitted transactions for a given date. Navigate to Reports → VFD Z-Report, select a date, and click Fetch.

Z-Reports are retrieved from the VFD server — ensure your device is registered and the API token is configured before requesting.

Reports

Over 40 report types covering sales, purchases, stock, finance, customers, suppliers, and VFD compliance. All reports accept common query parameters: from (start date), to (end date), warehouse_id, and where applicable user_id, client_id, or provider_id.

Reports

Sales report with date range filter and warehouse selector

Sales Reports

ReportPathDescription
Sales Report/api/report/salesAll sales with totals, filtered by date, warehouse, client
Sales by User/api/report/get_sales_by_userSales breakdown per salesperson
Sales by Product/api/report/get_sales_by_productRevenue and quantity per product
Product Sales Detail/api/report/sale_products_detailsLine-item details across all sales
Daily Transactions/api/report/daily-transactionsDay-by-day transaction summary
Monthly Transactions/api/report/monthly-transactionsMonth-by-month comparison
Last Sales/api/report/get_last_salesMost recent sales with quick summary
Top Products/api/report/top_productsBest-selling products ranked by revenue
Top Customers/api/report/top_customersHighest-revenue customers ranked
Sales by Warehouse/api/report/sales_warehouseRevenue comparison across all warehouses
Quotations by User/api/report/get_quotations_by_userQuotation activity per salesperson

Purchase Reports

ReportPathDescription
Purchases Report/api/report/purchasesAll purchases with totals, by date and supplier
Purchases by User/api/report/get_purchases_by_userPurchase activity per buyer/user
Purchases by Product/api/report/get_purchases_by_productCost and quantity per product purchased
Product Purchase Report/api/report/product_purchases_reportComprehensive product purchasing history
Purchase Returns by User/api/report/get_purchase_return_by_userReturns initiated per user

Stock & Inventory Reports

ReportPathDescription
Current Stock/api/report/stockStock level for every product at every warehouse
Low Stock Alerts/api/report/stock_alertProducts below their minimum reorder level
Warehouse Report/api/report/warehouse_reportFull activity (sales/purchases/transfers) per warehouse
Warehouse Stock Count/api/report/warhouse_count_stockPhysical stock count comparison per warehouse
Stock History/api/report/stock-historyAll movements (sales, purchases, adjustments, transfers) per product
Stock Valuation/api/report/stock-valuationCost value of current inventory per product
Inventory Valuation Summary/api/report/inventory_valuation_summaryTotal inventory value by category
Yearly Stock Summary/api/report/yearly-stock-summaryYear-over-year stock movement analysis
Transactions by Category/api/report/transactions-by-categorySales and purchase volumes grouped by product category
Transfers by User/api/report/get_transfer_by_userInter-warehouse transfer activity per user
Adjustments by User/api/report/get_adjustment_by_userStock adjustment history per user

Client & Supplier Reports

ReportPathDescription
Client Report/api/report/clientAll clients with total purchases, balance
Client Statement/api/report/client/{id}Full transaction history for one client
Client Sales/api/report/client_salesSales per client over a date range
Client Payments/api/report/client_paymentsPayment history per client
Client Returns/api/report/client_returnsReturn history per client
Client PDF/api/report/client_pdf/{id}Download client statement as PDF
Supplier Report/api/report/providerAll suppliers with total purchases, balance
Supplier Statement/api/report/provider/{id}Full transaction history for one supplier
Supplier Purchases/api/report/provider_purchasesPurchases per supplier
Supplier PO/api/report/provider_purchases_orderPurchase orders per supplier
Supplier Payments/api/report/provider_paymentsPayments made to each supplier
Supplier Returns/api/report/provider_returnsReturns sent to each supplier

Financial Reports

ReportPathDescription
Profit & Loss/api/report/profit_and_lossRevenue minus COGS and expenses over a period
Report Dashboard/api/report/report_dashboardSummary KPI cards for the reports overview page
Payment Chart/api/report/payment_chartVisual chart of incoming vs outgoing payments
Expenses by Warehouse/api/report/expenses_warehouseOperating expenses per branch
Sale Returns by Warehouse/api/report/returns_sale_warehouseSales return values per warehouse
Purchase Returns by Warehouse/api/report/returns_purchase_warehousePurchase return values per warehouse
Users Report/api/report/usersActivity summary (sales, purchases, etc.) per user
Expenses Report/api/report/expenses_reportAll expenses over a date range, filterable by warehouse and category
Deposits Report/api/report/deposits_reportAll deposits lodged over a date range, filterable by warehouse
Average Cost by Product/api/report/get_average_cost_by_productWeighted average purchase cost per product for COGS analysis
Average Cost (Chart)/api/report/averageCostChart data for average cost trend over time — used in the Analytics dashboard

Users & Roles

SmartVend uses role-based access control (RBAC). Every action in the system is gated behind a named permission. Roles group permissions together, and users are assigned one or more roles. This ensures each staff member can only access what their job requires.

Users and Roles

Figure 11 — Roles and permissions management

User Types

Super Admin

  • Bypasses all permission checks automatically — no role assignment needed
  • Full access to every module, every action, every record
  • Can create, edit, and delete other users including admins
  • Can toggle any user active/inactive

Regular Users

  • Must be assigned at least one role
  • Access determined by the union of permissions in all their roles
  • Navigation menu items are hidden when the user lacks the required permission
  • API enforces permissions server-side — UI hiding alone is not the security boundary

User Fields

FieldExampleNotes
NameJane SmithDisplay name throughout the system
Emailstaff@yourbusiness.comUsed for login and system notifications
Password••••••••Bcrypt hashed. Minimum 8 characters.
Phone+000 712 345 678Optional — used for internal SMS alerts
Role(s)Cashier, Reports ViewerMultiple roles can be assigned simultaneously
Avatar(Photo upload)Displayed in the top navigation bar
Is ActiveYesInactive users cannot log in even with valid credentials

Roles & Permissions

Roles are created at Settings → Roles. When creating a role, tick the permissions it should include. A user with the "Cashier" role would typically have Pos_view but not system_settings.

Permission Naming Convention

Format: ModuleName_action — e.g. Sales_add, Purchases_view

PermissionModuleAccess Granted
Sales
Sales_viewSalesView sales list and individual sale details
Sales_addSalesCreate new sales invoices
Sales_editSalesEdit existing sales invoices
Sales_deleteSalesDelete sales (soft-delete)
Point of Sale
Pos_viewPOSAccess the POS terminal interface and process checkout
Quotations
Quotations_viewQuotationsView quotation list and details
Quotations_addQuotationsCreate new price quotations
Quotations_editQuotationsEdit draft or sent quotations
Quotations_deleteQuotationsDelete quotations
Purchases & GRN
Purchases_viewPurchasesView purchase invoices and history
Purchases_addPurchasesCreate purchase invoices
Purchases_editPurchasesEdit existing purchase invoices
Purchases_deletePurchasesDelete purchase invoices
PurchaseOrders_viewPO & GRNView purchase orders and GRNs
PurchaseOrders_addPO & GRNCreate purchase orders and GRNs
PurchaseOrders_approvePO & GRNApprove purchase orders and GRNs — updates stock on GRN approval
Returns
Returns_viewReturnsView sale and purchase return documents
Returns_addReturnsCreate sale or purchase return documents
Returns_approveReturnsApprove returns — reverses stock and financial entries
Clients & Providers
Clients_viewClientsView customer list and profiles
Clients_addClientsCreate new customers
Clients_editClientsEdit customer details
Clients_deleteClientsDelete customer records
Providers_viewProvidersView supplier list and profiles
Providers_addProvidersCreate new suppliers
Providers_editProvidersEdit supplier details
Providers_deleteProvidersDelete supplier records
Payments
Payments_viewPaymentsView all payment records (sale, purchase, PO)
Payments_addPaymentsRecord new payments against sales or purchases
Payments_deletePaymentsDelete payment records (reverses balance)
Expenses & Deposits
Expenses_viewExpensesView expense records
Expenses_addExpensesCreate expense records
Expenses_editExpensesEdit expense records
Expenses_deleteExpensesDelete expense records
Expenses_approveExpensesApprove pending expenses before payment
Deposits_viewDepositsView deposit records
Deposits_addDepositsRecord new cash deposits
Inventory
Products_viewProductsView product catalog and stock levels
Products_addProductsCreate new products
Products_editProductsEdit product details, pricing, and variants
Products_deleteProductsDelete product records
Adjustments_viewAdjustmentsView stock adjustment documents
Adjustments_addAdjustmentsCreate stock adjustment documents
Adjustments_approveAdjustmentsApprove (or reject) stock adjustments — typically manager only
Transfers_viewTransfersView inter-warehouse stock transfers
Transfers_addTransfersCreate new stock transfer documents
Transfers_editTransfersEdit transfers before approval
Transfers_approveTransfersApprove, dispatch, and receive stock transfers
Accounting
Accounts_viewAccountsView chart of accounts and journal entries
Accounts_addAccountsCreate new accounts and post manual journal entries
Reports
Reports_salesReportsView sales reports section
Reports_purchasesReportsView purchase reports section
Reports_financialReportsView financial reports (P&L, accounts, expenses)
Reports_stockReportsView stock, inventory valuation, and stock movement reports
Administration
users_viewUsersView user list and profiles
users_addUsersCreate new user accounts
users_editUsersEdit user profiles and change role assignments
roles_viewRolesView roles and their permission sets
roles_addRolesCreate new roles
roles_editRolesEdit role permissions
audit_logs_viewAudit LogsView the audit log of all create/update/delete actions with before/after values
system_settingsSettingsModify all system settings — Super Admin only recommended
mail_settingsSettingsConfigure SMTP email and SMS gateway settings
Warehouses_viewWarehousesView warehouse list and details
Warehouses_addWarehousesCreate and edit warehouse locations
Categories_viewCatalogView product categories
Categories_addCatalogCreate and edit product categories and brands
Units_viewCatalogView units of measure
Units_addCatalogCreate and edit units of measure
Currencies_viewCatalogView currency list
Currencies_addCatalogAdd and configure currencies
backupMaintenanceTrigger database backups and manage backup files

Suggested Role Configurations

Role NameTypical PermissionsWho Gets It
CashierPos_view, Sales_viewCounter staff running POS
Sales ManagerSales_view/add/edit/delete, Clients_view/add, Quotations_view/add, Reports_salesField sales team leader
Store ManagerAdjustments_add/approve, Transfers_view/add/approve, Purchases_view, GRN_add/approveWarehouse / stock controller
AccountsExpenses_view/add, Deposits_view/add, Payments_view, Reports_financialFinance / accounting staff
Reports ViewerReports_sales, Reports_purchases, Reports_financialManagement (read-only)

API Endpoints

MethodEndpointDescription
GET/api/usersList all users (paginated)
POST/api/usersCreate a new user — assign name, email, password, roles
PUT/api/users/{id}Update user profile or change their role assignment
PUT/api/users_switch_activated/{id}Toggle user active/inactive status
GET/api/rolesList all roles with their permission sets
POST/api/rolesCreate a new role with selected permissions
PUT/api/roles/{id}Update role permissions
DELETE/api/roles/{id}Delete role (users keep their other roles)
GET/api/userGet current authenticated user info and permissions

System Settings

Configure all aspects of SmartVend from a single Settings page. Settings are stored in the database and take effect immediately — no server restart required. Only Super Admins or users with the system_settings permission can access this page.

Settings

Figure 12 — System settings with tabbed navigation

Company Information

Company info appears on all printed documents (invoices, POs, receipts, statements) and on the login page branding.

SettingExampleWhere It Appears
Company NameYour Business LtdLogin page, PDF header, all documents
Address123 Main Street, City CentrePDF documents
Phone+000 100 200 300PDF documents, footer
Emailinfo@yourbusiness.comPDF documents, email from address
Websitewww.yourbusiness.comPDF footer
Main Logo(PNG upload)Top-left of all pages (navbar)
PDF Logo(PNG upload)Printed on invoice/receipt PDFs

Invoice & Currency Settings

SettingExampleNotes
Default CurrencyTZS — Tanzanian ShillingShown on all invoices and reports. Must match a currency in the Currencies list.
Default Tax Rate18%Pre-filled when creating sales/purchases. Can be overridden per document.
Tax MethodInclusive / ExclusiveWhether product prices include tax (inclusive) or tax is added on top (exclusive)
Invoice PrefixSLPrepended to sale references: SL-MAIN-20260308-001
Invoice Footer NoteThank you for your business!Printed at the bottom of every sale PDF
Payment TermsNet 30 daysShown on invoices as payment due notice
Decimal Separator. (period)Controls number formatting on documents

Feature Flags

Feature flags allow you to enable or disable optional system behaviours without code changes. Toggle them in Settings → Feature Flags.

FlagWhen EnabledDefault
VFD IntegrationPOS checkout automatically submits to TRA VFD. Disable for testing environments or when VFD is not configured.On
Line Item DescriptionsA free-text description field appears for each line item on sale/purchase formsOff
Shift RequirementCashiers must open a shift before making any POS sale. System blocks checkout if no active shift exists.Off
Low Stock NotificationsSystem emails configured addresses when a product falls below its minimum reorder levelOff

POS Shift Configuration

When the shift requirement is enabled, this section controls how shifts behave.

SettingExampleNotes
Require ShiftYesIf Yes, POS checkout is blocked without an active shift for the logged-in user
Auto-End After (hours)10Shifts older than this are automatically closed — prevents forgetting to close at end of day
Configure via Settings → POS Settings or API at POST /api/settings/shift-config.

All Settings Tabs Summary

TabWhat You Can Configure
Company InfoCompany name, address, phone, email, logos, website
Invoice & CurrencyDefault currency, tax rate, invoice prefix, footer note, payment terms
VFD & TRAEnvironment (test/live), API token, TIN, VRN, serial number, UIN, tax office, brand colour
Email (SMTP)Mail host, port, username, password, encryption method, from name
SMS GatewayProvider, API token, sender ID, base URL
Feature FlagsVFD integration, line descriptions, shift requirement, low-stock alerts
POS & ShiftEnable shift requirement, auto-end timeout
WarehousesAdd/edit warehouse locations and per-branch VFD activation
ModulesInstall, enable, disable, and update add-on module packages
After changing any setting, click Clear Cache if the UI does not reflect the change immediately. This flushes the config and route cache on the server.

Module Management

SmartVend supports installable add-on modules — ZIP packages that extend the system with new features without modifying core files. Modules are managed from Settings → Modules.

ActionHow
View installed modulesSettings → Modules — lists all installed modules with version and status
Install a new moduleClick Upload Module, select the .zip package provided by your vendor
Enable / disable a moduleToggle the Active switch — disabled modules are not loaded and do not affect performance
Update a moduleUpload the new version ZIP — the system replaces files and runs any module migrations automatically

API Endpoints

MethodEndpointDescription
GET/api/get_modules_infoList all installed modules with name, version, and active status
POST/api/update_status_moduleEnable or disable a module ({ module: "ModuleName", status: true })
POST/api/upload_moduleUpload a module ZIP package (multipart/form-data)

API Reference

RESTful JSON API. All endpoints require Authorization: Bearer <token> except the public endpoints listed below. Rate limit: 120 req/min per user (auth: 5/min).

Authentication

# 1. Get access token (rate-limited: 5/min)
POST /api/getAccessToken
Content-Type: application/json

{
  "username":      "admin@example.com",
  "password":      "your_password",
  "client_id":     2,
  "client_secret": "get_from_oauth_clients_table",
  "grant_type":    "password"
}

# Response
{
  "access_token": "eyJ0eXAiOiJKV1Qi...",
  "token_type":   "Bearer",
  "expires_in":   31536000
}

# 2. Use in all subsequent requests
GET /api/sales
Authorization: Bearer eyJ0eXAiOiJKV1Qi...

# 3. Logout
POST /api/logout
The client_id and client_secret are generated by php artisan passport:install. Find the Password Grant client record in the oauth_clients database table.

Public Endpoints (No Auth)

MethodEndpointDescription
GET/api/healthDatabase health check — returns status and version
GET/api/brandingCompany name, logo URL, and theme color for login page
GET/api/pingKeep-alive / connection check
POST/api/getAccessTokenOAuth2 password grant — returns Bearer token
POST/api/password/createSend password reset link to email
POST/api/password/resetComplete password reset with token

Response Format

// Paginated list
{
  "data": [ { "id": 1, ... } ],
  "current_page": 1,
  "last_page":    5,
  "per_page":     10,
  "total":        48
}

// Single resource
{ "id": 1, "reference": "SL-MAIN-20260308-001", ... }

// Error
{ "message": "You are not authorized", "status": 403 }

// Validation error
{ "errors": { "amount": ["The amount field is required"] } }

Request & Response Examples

All requests below assume Authorization: Bearer <token> and Content-Type: application/json headers are set. Amounts are in Tanzanian Shilling (TZS).

POST /api/sales — Create Sale

// REQUEST
POST /api/sales
{
  "warehouse_id":  1,
  "client_id":     12,
  "date":          "2026-03-08",
  "discount":      0,
  "shipping":      5000,
  "tax_rate":      18,
  "tax_method":    "inclusive",
  "notes":         "Deliver to cold storage B2",
  "payment":       200000,
  "account_id":    2,
  "payment_method": "Bank Transfer",
  "details": [
    {
      "product_id": 1,
      "quantity":   25,
      "unit_price": 12500,
      "discount":   0,
      "unit_id":    1
    }
  ]
}

// RESPONSE 200
{
  "id":             382,
  "reference":     "SL-MAIN-20260308-001",
  "client_id":     12,
  "client_name":   "City Mart Traders Ltd",
  "warehouse_id":  1,
  "date":          "2026-03-08",
  "GrandTotal":    317500,
  "paid_amount":   200000,
  "due_amount":    117500,
  "payment_status": "partial",
  "vfd_status":    "submitted",
  "vfd_receipt_no": "20260308-MAIN-00382"
}

GET /api/sales/{id} — Sale Details

// REQUEST
GET /api/sales/382

// RESPONSE 200
{
  "id":              382,
  "reference":      "SL-MAIN-20260308-001",
  "date":           "2026-03-08",
  "warehouse":      "Headquarters",
  "client":         "City Mart Traders Ltd",
  "GrandTotal":     317500,
  "paid_amount":    200000,
  "due_amount":     117500,
  "payment_status": "partial",
  "details": [
    {
      "product_name": "Broiler Chicken (Dressed)",
      "quantity":     25,
      "unit_price":   12500,
      "total":        312500
    }
  ],
  "payments": [
    {
      "id": 85,
      "Ref":    "PAY-SL-2026-0085",
      "date":   "2026-03-08",
      "montant": 200000,
      "account": "CRDB Bank Account"
    }
  ]
}

POST /api/payment_sale — Record Sale Payment

// REQUEST
POST /api/payment_sale
{
  "sale_id":        382,
  "client_id":      12,
  "account_id":     2,
  "date":           "2026-03-09",
  "montant":        117500,
  "reglement":      "Bank Transfer",
  "notes":          "Final settlement"
}

// RESPONSE 200
{
  "id":             86,
  "Ref":            "PAY-SL-2026-0086",
  "date":           "2026-03-09",
  "montant":        117500,
  "reglement":      "Bank Transfer",
  "sale_id":        382,
  "client_id":      12,
  "account_id":     2
}

POST /api/purchases — Create Purchase Invoice

// REQUEST
POST /api/purchases
{
  "provider_id":   5,
  "warehouse_id":  1,
  "date":          "2026-03-08",
  "discount":      2,
  "shipping":      15000,
  "tax_rate":      18,
  "tax_method":    "exclusive",
  "grn_id":        14,
  "notes":         "Linked to GRN-000014",
  "payment":       1000000,
  "account_id":    2,
  "details": [
    {
      "product_id": 1,
      "quantity":   200,
      "cost":       8000,
      "discount":   0,
      "unit_id":    3
    }
  ]
}

// RESPONSE 200
{
  "id":              1042,
  "Ref":             "PR_1042",
  "provider_name":   "Prime Distributors Ltd",
  "GrandTotal":      1888000,
  "paid_amount":     1000000,
  "due_amount":      888000,
  "payment_status":  "partial",
  "grn_id":          14
}

POST /api/expenses — Create Expense

// REQUEST
POST /api/expenses
{
  "warehouse_id":    1,
  "account_id":      1,
  "expense_category_id": 3,
  "description":    "Delivery vehicle fuel — City to Region route",
  "amount":         85000,
  "date":           "2026-03-08",
  "note":           "Supplier receipt attached"
}

// RESPONSE 201
{
  "id":                  23,
  "Ref":                 "EXP-2026-0023",
  "description":        "Delivery vehicle fuel — City to Region route",
  "amount":             85000,
  "date":               "2026-03-08",
  "status":             "pending",
  "expense_category":   "Fuel & Transport",
  "warehouse":          "Headquarters"
}

POST /api/expenses/approve/{id} — Approve Expense

// REQUEST (no body required)
POST /api/expenses/approve/23

// RESPONSE 200
{
  "id":      23,
  "status": "approved",
  "amount": 85000,
  "message": "Expense approved. Account 111000 reduced by 85000."
}

POST /api/grn/create — Create GRN

// REQUEST — Direct GRN (no prior PO)
POST /api/grn/create
{
  "order_id":      null,
  "provider_id":   5,
  "warehouse_id":  1,
  "date":          "2026-03-08",
  "notes":         "15 birds rejected on QC — disease symptoms",
  "details": [
    {
      "product_id": 1,
      "quantity":   200,
      "cost":       8000
    }
  ]
}

// RESPONSE 200
{
  "id":             14,
  "Ref":            "GRN-000014",
  "provider_name": "Prime Distributors Ltd",
  "warehouse":     "Headquarters",
  "date":          "2026-03-08",
  "status":        "pending",
  "order_id":      null
}

POST /api/grn/approve/{id} — Approve GRN (updates stock)

// REQUEST (no body)
POST /api/grn/approve/14

// RESPONSE 200
{
  "id":      14,
  "Ref":     "GRN-000014",
  "status": "approved",
  "message": "Stock updated at Main Warehouse: Product A +200 units."
}

POST /api/transfers — Create Stock Transfer

// REQUEST
POST /api/transfers
{
  "from_warehouse_id": 1,
  "to_warehouse_id":   4,
  "date":              "2026-03-08",
  "notes":             "Weekly East Depot restock — cold chain truck 7am",
  "details": [
    {
      "product_id": 1,
      "quantity":   80,
      "unit_id":    1
    }
  ]
}

// RESPONSE 200
{
  "id":              19,
  "Ref":             "TR-2026-0019",
  "from_warehouse": "Main Warehouse",
  "to_warehouse":   "East Depot",
  "date":           "2026-03-08",
  "status":         "draft"
}

POST /api/adjustments — Create Stock Adjustment

// REQUEST
POST /api/adjustments
{
  "warehouse_id": 2,
  "date":         "2026-03-08",
  "notes":        "Freezer malfunction — product spoiled overnight",
  "details": [
    {
      "product_id": 3,
      "quantity":   15,
      "type":       "-"
    }
  ]
}

// RESPONSE 200
{
  "id":          11,
  "Ref":         "ADJ-2026-0011",
  "warehouse":  "North Branch",
  "date":        "2026-03-08",
  "status":      "pending"
}

POST /api/clients — Create Client

// REQUEST
POST /api/clients
{
  "name":           "City Mart Traders Ltd",
  "phone":          "+000 712 345 678",
  "email":          "orders@citymart.com",
  "adresse":        "City Centre",
  "city":           "Dar es Salaam",
  "tax_number":     "TAX-123-456-789",
  "credit_limit":   5000000,
  "opening_balance": 0
}

// RESPONSE 201
{
  "id":             12,
  "name":           "City Mart Traders Ltd",
  "phone":          "+000 712 345 678",
  "email":          "orders@citymart.com",
  "tax_number":     "TAX-123-456-789",
  "credit_limit":   5000000,
  "total_amount":   0,
  "paid_amount":    0,
  "due_amount":     0
}

GET /api/dashboard_data — Dashboard KPIs

// REQUEST
GET /api/dashboard_data?start_date=2026-03-01&end_date=2026-03-08&warehouse_id=1

// RESPONSE 200
{
  "total_sales":     4850000,
  "total_purchases": 2340000,
  "total_expenses":  480000,
  "total_profit":    2030000,
  "top_products": [
    { "name": "Broiler Chicken (Dressed)", "revenue": 3125000 },
    { "name": "Chicken Wings",             "revenue": 840000  }
  ],
  "stock_alerts": [
    { "product": "Product A", "warehouse": "NORTH", "qty": 45, "alert": 50 },
    { "product": "Product B",  "warehouse": "SOUTH", "qty": 0,  "alert": 20 }
  ]
}

GET /api/sales — List Sales (Paginated)

// REQUEST
GET /api/sales?page=1&per_page=10&start_date=2026-03-01&end_date=2026-03-08&warehouse_id=1&search=Karibu

// RESPONSE 200
{
  "data": [
    {
      "id":              382,
      "reference":      "SL-MAIN-20260308-001",
      "date":           "2026-03-08",
      "client_name":    "City Mart Traders Ltd",
      "warehouse":      "Headquarters",
      "GrandTotal":     317500,
      "paid_amount":    200000,
      "due_amount":     117500,
      "payment_status": "partial",
      "vfd_status":     "submitted"
    }
  ],
  "current_page": 1,
  "last_page":    3,
  "per_page":     10,
  "total":        28
}

Common Error Responses

// 401 Unauthenticated
{ "message": "Unauthenticated." }

// 403 Forbidden (permission missing)
{ "message": "You are not authorized to perform this action.", "status": 403 }

// 422 Validation Error
{
  "message": "The given data was invalid.",
  "errors": {
    "warehouse_id": ["The warehouse id field is required."],
    "details":      ["The details field must have at least 1 item."]
  }
}

// 429 Rate Limited
{ "message": "Too Many Attempts. Please retry after 60 seconds." }

// 502 VFD Upstream Error
{ "message": "VFD service unavailable. The receipt will be queued for retry.", "status": 502 }

All Endpoints by Module

Dashboard & System

MethodEndpointDescription
GET/api/dashboard_dataKPI cards: sales, purchases, expenses, profit
POST/api/clear_cacheClear application cache
GET/api/get_version_infoApplication version and update info
GET/api/userAuthenticated user info
GET/api/audit-logsPaginated audit log (filterable)
GET/api/audit-logs/statsActivity count summary

Products & Catalog

MethodEndpointDescription
GET/api/productsList products
POST/api/productsCreate product
GET/api/products/{id}Product details + stock
PUT/api/products/{id}Update product
DELETE/api/products/{id}Delete product
GET/api/categoriesList categories (CRUD available)
GET/api/brandsList brands (CRUD available)
GET/api/unitsList units (CRUD available)
GET/api/currenciesList currencies (CRUD available)
GET/api/packagesCombo/bundle products
GET/api/get_products_stock_alertsProducts below reorder level
POST/api/products/import/csvBulk import products
GET/api/count_stockGet current stock for physical count
POST/api/store_count_stockSubmit physical count (reconciles stock)

Sales

MethodEndpointDescription
GET/api/salesList sales
POST/api/salesCreate sale
GET/api/sales/{id}Sale details
PUT/api/sales/{id}Update sale
DELETE/api/sales/{id}Delete sale
GET/api/sale_pdf/{id}Download sale PDF
GET/api/sales/{id}/preview-vfdVFD receipt preview
POST/api/sales/{id}/resubmit-vfdResubmit to VFD
GET/api/payment_saleList sale payments
POST/api/payment_saleRecord sale payment
GET/api/returns/saleList sale returns
POST/api/returns/saleCreate sale return
POST/api/returns/sale/approve/{id}Approve sale return (restores stock)

POS

MethodEndpointDescription
POST/api/pos/create_posComplete POS checkout
GET/api/pos/get_products_posProducts for POS at active warehouse
GET/api/pos/data_create_posPOS initialization data
POST/api/pos/create_draftSave POS cart as draft
GET/api/get_draft_salesList saved drafts
DELETE/api/remove_draft_sale/{id}Delete draft
POST/api/shift-sessions/startOpen shift
POST/api/shift-sessions/endClose shift
POST/api/shift-sessions/approveApprove shift

Purchases & POs

MethodEndpointDescription
GET/api/purchasesList purchases
POST/api/purchasesCreate purchase invoice
GET/api/purchase_ordersList purchase orders
POST/api/purchase_ordersCreate purchase order
POST/api/purchase_order/submit/{id}Submit PO for approval
POST/api/purchase_order/approve/{id}Approve PO
POST/api/grn/createCreate GRN (set order_id=null for Direct GRN)
GET/api/grnsList all GRNs
GET/api/grn/{id}GRN details
POST/api/grn/approve/{id}Approve GRN — updates warehouse stock
GET/api/get_receive_data/{grnId}Pre-fill purchase form from GRN
GET/api/get_orderPOs, suppliers, warehouses for GRN creation form
GET/api/payment_purchaseList purchase payments
POST/api/payment_purchaseRecord supplier payment

Quotations

MethodEndpointDescription
GET/api/quotationsList quotations
POST/api/quotationsCreate quotation
PUT/api/quotations/{id}Update quotation
DELETE/api/quotations/{id}Delete quotation
GET/api/quote_pdf/{id}Download quotation PDF
GET/api/convert_to_sale_data/{id}Convert quotation to sale

Expenses, Deposits & Accounts

MethodEndpointDescription
GET/api/expensesList expenses
POST/api/expensesCreate expense
POST/api/expenses/approve/{id}Approve expense
GET/api/expenses_categoryList expense categories
GET/api/depositsList deposits
POST/api/depositsCreate deposit
GET/api/accountsList accounts (chart of accounts)
POST/api/accountsCreate account
GET/api/transfer_moneyList account-to-account transfers
POST/api/transfer_moneyTransfer money between accounts
GET/api/cash-collectionsList cash collections
POST/api/cash-collectionsRecord cash collection
GET/api/cash-collections/global-summaryTotal collections across all branches

Transfers & Adjustments

MethodEndpointDescription
GET/api/transfersList stock transfers
POST/api/transfersCreate transfer
POST/api/transfer/approve/{id}Approve transfer
POST/api/transfer/complete/{id}Mark completed (updates destination stock)
GET/api/adjustmentsList stock adjustments
POST/api/adjustmentsCreate adjustment
POST/api/adjustments/approve/{id}Approve adjustment (updates stock + journal)

VFD / TRA

MethodEndpointDescription
POST/api/vfd/invoiceSubmit a sale to VFD for tax receipt
GET/api/vfd/invoice/{id}Get VFD receipt status for a sale
GET/api/vfd/z-report/{date}Daily Z-Report (format: YYYY-MM-DD)
GET/api/vfd/tax-reportTax summary report from VFD
POST/api/vfd/receiptsList/search VFD receipts

Settings

MethodEndpointDescription
GET/api/settingsGet all system settings
POST/api/settingsUpdate system settings (company info, logo, currency, etc.)
POST/api/settings/vfd-configUpdate VFD API credentials and environment
POST/api/settings/shift-configUpdate shift session configuration
POST/api/settings/feature-flagsToggle optional features on/off
GET/api/get_pos_SettingsPOS-specific settings
PUT/api/pos_settings/{id}Update POS settings
GET/api/get_sms_configSMS gateway configuration
POST/api/update_sms_configUpdate SMS gateway settings
GET/api/get_config_mailSMTP mail configuration
PUT/api/update_config_mail/{id}Update SMTP settings
GET/api/warehousesList warehouses
POST/api/warehousesCreate warehouse
PUT/api/vfd_switch_activated/{id}Toggle VFD on/off for a warehouse
GET/api/rolesList roles with permissions
POST/api/rolesCreate role with permissions
GET/api/usersList users
POST/api/usersCreate user
PUT/api/users_switch_activated/{id}Activate / deactivate user
GET/api/get_backupList database backups
GET/api/generate_new_backupCreate new database backup
All list endpoints support query parameters: ?search=, ?page=, ?per_page=, ?sort_by=, ?sort_type=asc|desc, ?warehouse_id=, ?start_date=, ?end_date= where applicable.

Stock Counting

Perform physical stock counts and reconcile discrepancies against system quantities.

Stock Count Workflow

Go to Products → Count Stock Select Warehouse Enter Physical Counts Preview & Confirm Stock Reconciled
Stock counting replaces system quantities with the counted figures. Run counts during off-peak hours or when no transactions are in progress.

How It Works

  • Navigate to Products → Count Stock
  • The system pre-fills each product with its current system quantity
  • Enter the physically counted quantity for each product
  • The difference column shows over/under stock
  • Submit to apply — the system overwrites quantities and records the adjustment
  • Preview CSV import for bulk counting via spreadsheet

Example Count Sheet

The system pre-fills current quantities. Count staff enter actual physical quantities. Differences are highlighted automatically — positive means found stock, negative means missing stock.

ProductSystem QtyCounted QtyDifferenceLikely Cause
Product A320298–22Spoilage / damage / unrecorded write-off
Product B8591+6Unrecorded receipt / supplier over-delivery
Product C45450Matches — no action needed
Product D2000–200Out of stock — not available in this warehouse
Submitting a stock count overwrites system quantities with counted figures and records a reconciliation adjustment. Run counts when no transactions are in progress to avoid race conditions.

Best Practices for Stock Counts

  • Count during off-peak hours — early morning before operations begin, or after close of business
  • Freeze transactions while counting — pause POS sales and ask warehouse staff to hold receipts until the count is complete
  • Count by category, one product at a time — use the search / filter by category option to avoid mixing products
  • Use the CSV export to print a blank count sheet, do the physical count on paper, then enter results in the system
  • Investigate large discrepancies before submitting — check recent transfers, unapproved adjustments, or draft documents that may not be reflected in stock yet
  • After submission, review the auto-created adjustment document in Stock Adjustments to verify the reconciliation is correct
  • Run counts per warehouse — do not mix stock from different branches in the same count session

Stock Count API Endpoints

MethodEndpointDescription
GET/api/count_stock?warehouse_id={id}Return all products with current system quantities for a given warehouse
POST/api/store_count_stockSubmit counted quantities — reconciles and overwrites stock levels
GET/api/preview_count_stock/{filename}Preview a CSV count file before submitting

Stock Entries (Opening Stock)

Stock Entries are used to load initial stock quantities when setting up the system, or to record a full stock intake outside the normal GRN workflow. Unlike a stock count (which reconciles differences), a stock entry records a complete snapshot of quantities and costs per product. The entry stays in Draft until a manager approves it — at which point product quantities at the selected warehouse are updated.

Create Stock Entry Add Products & Quantities Manager Approves Warehouse Stock Updated

Stock Entry Fields

FieldExampleNotes
ReferenceSTK-2026-0003Auto-generated
Date08 March 2026Date of the physical stock intake
WarehouseMain WarehouseQuantities are applied to this warehouse only
Product(s)Multiple linesEach line: product, quantity, cost price
StatusDraft → ApprovedNo stock change until approved

CSV Import for Stock Entries

Upload a CSV to populate a stock entry in bulk. Required columns: code or name, quantity. Optional: cost, price, unit, category, brand (used to auto-create the product if it does not yet exist).

API Endpoints

MethodEndpointDescription
GET/api/stocksList all stock entries (paginated)
POST/api/stocksCreate a new stock entry (status: draft)
GET/api/stocks/{id}Stock entry detail with all product lines
PUT/api/stocks/{id}Edit stock entry before approval
DELETE/api/stocks/{id}Delete unapproved stock entry
GET/api/stocks/detail/{id}Line-item detail for a specific stock entry
POST/api/stock/approve/{id}Approve — updates warehouse stock quantities
POST/api/stock/importImport stock entry lines from CSV

Cash Collections

Track and reconcile cash collected by field sales reps, cashiers, or delivery staff across all branches. Managers review, approve, and post daily collections to the correct accounts.

Collection Workflow

Staff Collects Cash Records Collection in System Manager Reviews Posted to Account Appears in Reports

Cash Collections is designed for businesses where staff physically collect money on behalf of the company — field sales reps collecting payment from clients, delivery drivers accepting cash on delivery, or cashiers banking end-of-day float. Each record links to a user, a branch, and a receiving account so management can track exactly who collected what and where the money went.

Collection Record Fields

FieldExampleNotes
ReferenceCC-2026-0041Auto-generated sequential reference
Collected ByAlex SalesThe staff member who physically collected the money
BranchNorth BranchThe warehouse / branch where the collection occurred
Amount4,500Total amount collected (always positive)
AccountPetty Cash — North BranchThe account this cash is deposited into
Date08 March 2026Date the cash was physically received
NotesMarket day weekend collectionsInternal description of the source

Example Collection Record

Cash Collection: CC-2026-0041
FieldValue
ReferenceCC-2026-0041
Collected ByAlex Sales (Sales Representative)
BranchNorth Branch
Amount4,500
AccountPetty Cash — North Branch (111001)
Date08 March 2026
NotesWeekend market day collections from 3 clients

Dashboard Views

Management can view aggregated collection data across all branches without drilling into individual records.

ViewEndpointDescription
Global SummaryGET /api/cash-collections/global-summaryTotal amount collected across all branches and users for the selected date range
Branch SummaryGET /api/cash-collections/branchesBreakdown of collections per branch — shows which location collected most
User Summary by BranchGET /api/cash-collections/branch-user-summaryPer-user totals within each branch — shows individual staff performance
Pending AmountsGET /api/cash-collections/pending-amountsCollections recorded by staff that have not yet been reconciled or posted to account

API Endpoints

MethodEndpointDescription
GET/api/cash-collectionsList all collection records (paginated, filter by branch/user/date)
POST/api/cash-collectionsRecord a new cash collection — specify amount, collector, branch, account
PUT/api/cash-collections/{id}Edit a collection record
DELETE/api/cash-collections/{id}Delete a collection record
GET/api/cash-collections/global-summaryAggregated total across all branches
GET/api/cash-collections/branchesPer-branch breakdown
GET/api/cash-collections/branch-user-summaryPer-user totals within each branch
GET/api/cash-collections/pending-amountsUnreconciled collection records
POST/api/cash-collections/bulkPost multiple collection records in one request (bulk posting)
POST/api/cash-collections/delete/by_selectionBulk delete selected collection IDs

Money Transfers

Transfer funds between internal accounts — for example, replenishing petty cash from the bank, or moving funds from a branch account to head office. Both sides of the transfer are recorded atomically, maintaining ledger balance.

What Is a Money Transfer?

A money transfer moves a specified amount from one account in the chart of accounts to another — for example, from the business bank account to the petty cash account. The system debits the source account and credits the destination account simultaneously, so the books stay balanced at all times.

This is different from a Stock Transfer (which moves physical inventory between warehouses). A Money Transfer moves financial balances between accounts in the ledger only.

Common Use Cases

  • Replenish petty cash: withdraw from the main bank account into the petty cash account
  • Consolidate branch float: move end-of-day cash from branch account to head office account
  • Intercompany loan repayment: record a fund movement between two entity accounts
  • Correct a mis-posted payment: reverse and re-post to the correct account

Transfer Fields

FieldExampleNotes
ReferenceMT-2026-0012Auto-generated sequential number
From AccountBusiness Bank Account (112000)Account to debit — balance decreases
To AccountPetty Cash (111000)Account to credit — balance increases
Amount2,000Must be positive. Both accounts updated by this exact amount.
Date08 March 2026Date the transfer takes effect in the ledger
NotesWeekly petty cash top-upInternal description — appears in account journal history
Ensure the From Account has sufficient balance before transferring. The system does not block overpayments automatically — negative balances are permitted but will appear in the chart of accounts as warnings.

Example Transfers

Transfer: MT-2026-0012 — Petty Cash Top-Up
FieldValue
ReferenceMT-2026-0012
From AccountBusiness Bank Account (112000)
To AccountPetty Cash (111000)
Amount2,000
Date08 March 2026
NotesWeekly petty cash top-up — Monday morning
Transfer: MT-2026-0013 — Branch Float Consolidation
FieldValue
ReferenceMT-2026-0013
From AccountNorth Branch Cash (111001)
To AccountBusiness Bank Account (112000)
Amount15,000
Date08 March 2026
NotesEnd-of-week branch float banked — North Branch

Accounting Effect

Every money transfer creates an automatic journal entry — debiting the source and crediting the destination. You can view this entry in Accounts → Journal Entries, filtered by reference MT-2026-0012.

AccountEffectAmountWhy
Business Bank Account (112000)DR2,000Money leaves the bank — asset decreases
Petty Cash (111000)CR2,000Money arrives in petty cash — asset increases
Both accounts are updated in a single database transaction — they either both succeed or both fail. There is no risk of one side updating without the other.

API Endpoints

MethodEndpointDescription
GET/api/transfer_moneyList all money transfers (paginated, filter by date/account)
POST/api/transfer_moneyCreate a new money transfer — specify from_account_id, to_account_id, amount, date
GET/api/transfer_money/{id}Full details of a specific transfer including journal entry reference
DELETE/api/transfer_money/{id}Delete a money transfer and reverse the journal entry

Pending Amounts

Monitor money owed to the business that has not yet been collected or posted — a real-time view of outstanding field receivables broken down by branch and individual staff member.

What Are Pending Amounts?

A pending amount is a financial obligation that has been recorded in the system but not yet settled. This is most common in field sales operations where a sales rep delivers goods on credit, collects cash over time, and gradually remits it to the branch. The pending amount tracks the gap between what is owed and what has been received.

The module works alongside Cash Collections:

ModuleTracksExample
Pending AmountsMoney still outstanding — expected but not yet receivedSales rep owes 10,000 from client deliveries this week
Cash CollectionsMoney received — physically collected and recordedSales rep deposited 6,000 from last week's collections
DifferenceThe remaining gap that needs to be resolvedOutstanding: 4,000 still not received

Pending Amount Fields

FieldExampleNotes
ReferencePA-2026-0019Auto-generated sequential number
Staff MemberAlex SalesThe person responsible for collecting this amount
BranchNorth BranchThe branch this amount is associated with
Amount10,000Total amount expected from this staff member
Collected6,000Amount already received via Cash Collections
Outstanding4,000Calculated: Amount − Collected. Highlighted in red when overdue.
Due Date15 March 2026When the full amount is expected to be remitted
NotesClient deliveries week of 3 MarchDescription of the source of this pending amount

Example Pending Amount

Pending Amount: PA-2026-0019
FieldValue
ReferencePA-2026-0019
StaffAlex Sales (North Branch)
Total Due10,000
Collections Received6,000 (recorded in Cash Collections CC-2026-0038, CC-2026-0041)
Outstanding4,000
Due Date15 March 2026
StatusPartial — 4,000 still outstanding

Management Views

Management can view pending amounts at different levels of detail — from a global company-wide view down to individual staff members.

  • Summary view — total pending across all branches and all staff in one number
  • Branch view — per-branch outstanding totals — shows which location has the most uncollected cash
  • User view — within each branch, a breakdown per staff member — identifies who needs to remit funds urgently
  • Overdue filter — highlight records past their due date for follow-up

API Endpoints

MethodEndpointDescription
GET/api/cash-collections/pending-amountsList all pending amounts (paginated, filter by branch/user/date/status)
POST/api/cash-collections/pending-amountsCreate a new pending amount record — specify staff, branch, amount, due date
PUT/api/cash-collections/pending-amounts/{id}Update a pending amount (e.g. revise due date or expected total)
DELETE/api/cash-collections/pending-amounts/{id}Delete a pending amount record
GET/api/cash-collections/branch-user-summaryPer-user outstanding totals grouped by branch

SMS & Email Notifications

Configure gateway credentials and customize notification templates for SMS and email communications.

SMS Gateway Configuration

SmartVend supports a configurable SMS gateway for sending sale invoices, payment receipts, purchase orders, and quotations directly to clients and suppliers via SMS.

SettingDescription
Gateway NameSMS provider name (e.g. Africa's Talking, Bongolive)
API TokenProvider authentication token
Sender IDSender name shown on recipient's phone
Base URLGateway API endpoint
Navigate to Settings → SMS Settings to configure. Use the Test SMS button to verify connectivity before saving.

Email (SMTP) Configuration

SettingExample Value
Mail Hostsmtp.gmail.com
Port587
Usernamenotifications@yourbusiness.com
PasswordApp password (stored encrypted)
Encryptiontls
From NameSmartVend
Email settings take effect immediately after saving. Test with the Send Test Email button before putting into production.

Notification Templates

Customize the body of SMS and email messages sent by the system. Template variables use {variable} syntax.

TemplateTriggerAvailable Variables
Sale InvoiceSend invoice to client{client_name}, {reference}, {total}, {due_date}
Payment ReceiptPayment recorded{client_name}, {amount}, {balance}
Purchase OrderSend PO to supplier{supplier_name}, {reference}, {total}
QuotationSend quote to client{client_name}, {reference}, {valid_until}
Navigate to Settings → Notifications to edit templates. Changes apply to all future sends immediately.

Currencies, Units & Catalog Settings

Manage currencies, measurement units, product categories, and brands used across the system.

Currencies

Define currencies for multi-currency pricing. The default currency is set in System Settings. Only one currency is active at a time for transactions.

FieldExample
NameTanzanian Shilling
CodeTZS
SymbolTZS

Units of Measurement

Define base units and sub-units. Sub-units have a fixed conversion factor to their base unit, enabling selling in different packaging.

Example Unit with Sub-unit
UnitTypeConversion
KgBase Unit
PieceSub-unit of Kg1 Piece = 1.8 Kg
Half ChickenSub-unit of Kg1 Half = 0.9 Kg

Categories & Brands

Product Categories

  • Hierarchical (parent → sub-category)
  • Used for filtering reports and products
  • Example: Poultry → Fresh / Frozen / Processed

Brands

  • Associate products with a brand
  • Used in product list filtering
  • Example: Interchick, Tanpro
Manage via Settings → Warehouses (for warehouse config) and Products → Categories / Brands / Units in the navigation.

Backup & Maintenance

Database backups and system maintenance tools for administrators.

Database Backups

  • Generate a new backup snapshot on demand
  • List all existing backup files with timestamps and sizes
  • Download any backup file to local storage
  • Delete individual backup files to free server space
Backups are stored on the server. Set up a cron job or external backup strategy to copy files off-site. Deleting a backup is irreversible.

API Endpoints

MethodEndpointAction
GET/api/get_backupList all backups
GET/api/generate_new_backupCreate new backup
DELETE/api/delete_backup/{name}Delete specific backup

Cache Management

If the system shows stale data after configuration changes, clear the application cache.

# Via API
POST /api/clear_cache
Authorization: Bearer <token>

# Or via Artisan
php artisan config:clear
php artisan cache:clear
php artisan route:clear
Cache clearing is also available in the UI under Settings → Clear Cache button. Use this after changing environment variables or system settings.

Module Management

Optional modules can be enabled or disabled without code changes. Disabled modules are hidden from navigation.

ActionEndpoint
List module statusGET /api/get_modules_info
Toggle module on/offPOST /api/update_status_module
Upload new module packagePOST /api/upload_module

Audit Logs

Complete tamper-evident activity log — every create, update, and delete action is recorded with the acting user and timestamp.

What Is Logged

  • All CRUD operations on business records (sales, purchases, payments, etc.)
  • User ID and username of the person who performed the action
  • Model name and record ID affected
  • HTTP method, route, and IP address
  • Before and after values for updates (when available)
  • Timestamp (created_at)

Example Log Entry

Audit Log: ID 2041
FieldValue
Useradmin (ID: 1)
Actionupdated
ModelSale
Record ID382
DescriptionUpdated sale SL-MAIN-20260308-001 — changed payment status to Paid
IP Address192.168.1.10
Timestamp2026-03-08 14:32:17

API Endpoints

MethodEndpointDescription
GET/api/audit-logsList audit logs (paginated, filterable by user/model/date)
GET/api/audit-logs/statsActivity summary counts
GET/api/audit-logs/{id}Full detail for a single log entry
Access audit logs via System → Audit Logs in the navigation. Only Super Admin users can view audit logs by default.

License & Billing

SmartVend requires an active license to operate. This page covers license activation, subscription management, and how to check your current license status.

How Licensing Works

Each SmartVend installation requires a valid license key tied to your domain. The license is validated against the billing server on startup and periodically during operation. If the license expires or becomes invalid, access to protected features is restricted until the license is renewed.

ConceptExplanation
License KeyA unique key issued per installation. Tied to the domain / IP of your server.
SubscriptionLicense keys have a validity period. Subscriptions must be renewed before expiry to avoid interruption.
Billing ServerSmartVend calls an external billing server to verify license validity. Ensure your server has outbound internet access to the billing endpoint.
Grace PeriodA short grace period may be granted after expiry before features are locked, allowing time to renew without downtime.

Activating Your License

1

Navigate to License Settings

Go to Settings → License & Billing or navigate directly to /settings#license in the app.

2

Enter Your License Key

Paste the license key you received after purchase into the License Key field. Click Activate.

3

System Verifies with Billing Server

SmartVend contacts the billing server to validate the key. On success, the license details (expiry date, plan) are stored locally and displayed on the page.

4

Confirm Activation

A Active status badge appears with your plan name and expiry date. All features are now unlocked.

Each license key can only be active on one domain at a time. If you move the system to a new server, contact support to transfer the license.

Billing Server Configuration

The billing server URL is pre-configured in the system. If your installation uses a private billing server, update it under Settings → Billing Config.

SettingDescription
Billing Server URLBase URL of the licensing/billing API. Do not include a trailing slash.
Connection TimeoutMaximum seconds to wait for a billing server response before falling back to cached license data. Default: 10s.
Use Settings → Test Billing Connection to verify connectivity to the billing server before activating.

Subscription Status & Renewal

StatusMeaningAction
ActiveLicense is valid and verified. All features accessible.No action needed.
Expiring SoonLicense expires within 14 days. System continues to function normally.Renew via billing portal before expiry.
ExpiredLicense period has ended. Some features may be locked.Renew and re-activate with the new key.
UnverifiedCould not contact billing server. Running on cached license data.Check internet connectivity; billing server may be down temporarily.

API Endpoints

MethodEndpointDescription
GET/api/licenseGet current license status — returns plan, expiry date, and activation state
POST/api/license/activateActivate or re-activate using a license key: { "license_key": "XXXX-XXXX-XXXX-XXXX" }
POST/api/billing/test-connectionTest connectivity to the billing server — returns { "success": true } on reachable
POST/api/billing/check-subscriptionForce a fresh subscription check against the billing server

VFMS / ZRA (Zanzibar)

SmartVend supports the Zanzibar Revenue Authority (ZRA) Virtual Fiscal Machine Service for businesses operating in Zanzibar. VFMS reporting runs alongside or independently of VFD/TRA.

Enabling VFMS

Set VFMS_ENABLED=true in .env or enable via Settings → Feature Flags. Once enabled, VFMS reports appear under Reports → VFMS.

Available Reports

ReportEndpointDescription
VFMS ReceiptsPOST /api/vfms/receiptsList of submitted fiscal receipts with status
VFMS Tax ReportGET /api/vfms/tax-reportTax summary report for a date range
VFMS Error ReportGET /api/vfms/error-reportFailed submissions and error details for troubleshooting

Shift Sessions

Shift sessions enforce cash accountability by requiring users to open and close shifts before processing sales. Each warehouse tracks shifts independently.

Shift Workflow

Start Shift
Process Sales
End Shift
Manager Approval
  • Shift required per warehouse before POS transactions
  • Opening float and closing balance recorded
  • Automatic shift auto-end at configured time
  • Manager can approve or reject shift closings
  • Shift history and audit trail per user

Configuration

Configure shift settings via Settings → Shift Config or POST /api/settings/shift-config.

SettingDescription
Shift RequiredWhen enabled, POS transactions are blocked until a shift is started
Auto-End TimeAutomatically ends open shifts at a set time (e.g. midnight)
Require ApprovalManager must approve shift closure before totals are finalized

API Endpoints

MethodEndpointDescription
GET/api/shift-sessionsList all shift sessions (filterable by warehouse, date, user)
GET/api/shift-sessions/currentGet the current user's active shift
POST/api/shift-sessions/startStart a new shift for a warehouse
POST/api/shift-sessions/endEnd the current shift with closing totals
POST/api/shift-sessions/approveManager approves a closed shift
POST/api/shift-sessions/rejectManager rejects a shift (requires re-closing)

Snippe Payment Gateway

Snippe integration enables mobile money and bank payment collection directly from SmartVend. Customers can pay via USSD push or bank transfer, and the system tracks payment status in real time via webhooks.

Configuration

Configure via Settings → Snippe or set in .env:

VariableDescription
SNIPPE_API_URLSnippe API base URL
SNIPPE_API_KEYYour API key for authentication
SNIPPE_WEBHOOK_SECRETHMAC secret for verifying webhook signatures

Features

  • Payment Collection — Create payment requests for customers (mobile money, bank)
  • Push Payment — Send USSD push prompts to customer phones
  • Payouts — Send money to suppliers or refund customers
  • Balance Check — View current Snippe account balance
  • Webhook Verification — Incoming webhooks are validated via HMAC signature
  • Status Tracking — Real-time payment status updates (pending, completed, failed)

API Endpoints

MethodEndpointDescription
POST/api/snippe/paymentsCreate a new payment request
GET/api/snippe/paymentsList payment records
GET/api/snippe/payments/balanceCheck Snippe account balance
GET/api/snippe/payments/{ref}/statusCheck payment status by reference
POST/api/snippe/payments/{ref}/pushPush payment prompt to customer
POST/api/snippe/payouts/sendSend payout to a recipient
GET/api/snippe/payoutsList payouts
POST/api/snippe/webhookWebhook receiver (no auth, HMAC verified)

WhatsApp & Messaging

Send transaction documents (invoices, quotations, purchase orders) directly to customers and suppliers via WhatsApp, SMS, or email from any transaction detail page.

WhatsApp Delivery

On any sale, purchase, or quotation detail page, click the WhatsApp button to send the document. The system generates a shareable message with transaction details.

TransactionEndpoint
SalesPOST /api/sales_send_whatsapp
PurchasesPOST /api/purchase_send_whatsapp
Purchase OrdersPOST /api/purchase_order_send_whatsapp
QuotationsPOST /api/quotation_send_whatsapp

Email & SMS

Every transaction type supports email and SMS delivery. Templates are customizable under Settings → SMS Templates and Settings → Email Templates.

  • Customizable SMS templates with merge fields (customer name, amount, reference)
  • Custom email templates with HTML body editor
  • Test SMS feature to verify gateway connectivity
  • Configurable SMS gateway (any HTTP-based provider)

Module Management

SmartVend supports a modular architecture where features can be enabled, disabled, or extended via installable modules.

Feature Flags

Toggle features on/off via Settings → Feature Flags or POST /api/settings/feature-flags:

FlagDescription
feature_vfdVFD / TRA fiscal device integration
feature_vfmsVFMS / ZRA reporting (Zanzibar)
feature_smsSMS notifications
feature_quotationsQuotation module
feature_purchase_returnsPurchase returns
feature_sale_returnsSale returns
feature_expensesExpense tracking
feature_combo_productsCombo/bundle products
feature_shiftsShift session management
feature_multi_warehouseMulti-warehouse operations
feature_snippeSnippe payment gateway

Installable Modules

Additional modules can be uploaded as ZIP files via Settings → Modules. Each module can include its own migrations, routes, controllers, and views.

MethodEndpointDescription
GET/api/get_modules_infoList all installed modules with status
POST/api/update_status_moduleEnable or disable a module
POST/api/upload_moduleUpload and install a new module (ZIP)