Petty Cash
Petty cash management allows companies to maintain small cash funds for day-to-day minor expenses. Each petty cash fund is assigned a custodian (a user responsible for the fund), linked to a GL account, and has a maximum allowed amount. Transactions (receipts and payments) adjust the fund balance and can optionally generate journal entries.
Purpose
- Create and manage petty cash funds with assigned custodians
- Track receipt (replenishment) and payment (expense) transactions
- Maintain a running balance with automatic adjustment on each transaction
- Enforce fund limits to prevent overspending
- Link each fund to a GL account for ledger integration
- Provide a clear audit trail of all petty cash activity
Entity Attributes
Petty Cash (Fund)
| Field | Type | Description |
|---|---|---|
id | bigint | Primary key |
company_id | bigint | FK to companies |
name | string | English name (e.g., "Main Office Petty Cash") |
name_ar | string? | Arabic name (e.g., "صندوق المصروفات النثرية - المكتب الرئيسي") |
account_id | bigint | FK to accounts (linked GL account) |
custodian_id | bigint? | FK to users (responsible person) |
max_amount | decimal(12,3) | Maximum fund limit |
current_balance | decimal(12,3) | Current available balance — derived from posted GL activity, never written directly |
is_active | boolean | Whether the fund is active |
created_at | timestamp | Creation timestamp |
updated_at | timestamp | Last update timestamp |
deleted_at | timestamp? | Soft-delete timestamp |
Petty Cash Transaction
| Field | Type | Description |
|---|---|---|
id | bigint | Primary key |
company_id | bigint | FK to companies |
petty_cash_id | bigint | FK to petty_cash |
type | enum | receipt (replenishment) or payment (expense) |
amount | decimal(12,3) | Transaction amount |
date | date | Transaction date |
description | string | English description |
description_ar | string? | Arabic description |
reference | string? | External reference (receipt number, voucher, etc.) |
journal_entry_id | bigint? | FK to journal_entries (auto-generated) |
created_by | bigint? | FK to users |
created_at | timestamp | Creation timestamp |
updated_at | timestamp | Last update timestamp |
INFO
Petty cash transactions do not use soft deletes. When a transaction is deleted, its journal entry is reversed.
Single source of truth
current_balance is derived from the petty cash GL account's posted activity by PettyCashBalanceService::syncBalance() — it is re-synced after every transaction and never mutated directly. Payment sufficiency is checked against this GL-derived balance, so a stale current_balance can never authorise an overspend.
:::
Relationships
Transaction Types
| Type | Value | Effect on Balance | Description |
|---|---|---|---|
| Receipt | receipt | Increases balance | Fund replenishment from main cash/bank |
| Payment | payment | Decreases balance | Expense payment from the fund |
API Endpoints
Petty Cash Funds
| Method | Path | Description |
|---|---|---|
GET | /api/accounting/petty-cash | List petty cash funds (paginated) |
POST | /api/accounting/petty-cash | Create a new petty cash fund |
GET | /api/accounting/petty-cash/{id} | Get a single fund |
PUT | /api/accounting/petty-cash/{id} | Update a fund |
DELETE | /api/accounting/petty-cash/{id} | Soft-delete a fund |
Petty Cash Transactions
| Method | Path | Description |
|---|---|---|
GET | /api/accounting/petty-cash/{id}/transactions | List transactions for a fund |
POST | /api/accounting/petty-cash/{id}/transactions | Create a transaction |
GET | /api/accounting/petty-cash/{id}/transactions/{txId} | Get a transaction |
DELETE | /api/accounting/petty-cash/{id}/transactions/{txId} | Delete and reverse a transaction |
Request/Response Examples
Create Petty Cash Fund
Request POST /api/accounting/petty-cash
curl -X POST https://moon-erp.test/api/accounting/petty-cash \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Main Office Petty Cash",
"name_ar": "صندوق المصروفات النثرية - المكتب الرئيسي",
"account_id": 3,
"custodian_id": 2,
"max_amount": "500.000",
"is_active": true
}'final response = await http.post(
Uri.parse('https://moon-erp.test/api/accounting/petty-cash'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: jsonEncode({
'name': 'Main Office Petty Cash',
'name_ar': 'صندوق المصروفات النثرية - المكتب الرئيسي',
'account_id': 3,
'custodian_id': 2,
'max_amount': '500.000',
'is_active': true,
}),
);Response 201 Created
{
"data": {
"id": 1,
"company_id": 1,
"name": "Main Office Petty Cash",
"name_en": "Main Office Petty Cash",
"name_ar": "صندوق المصروفات النثرية - المكتب الرئيسي",
"account_id": 3,
"account": {
"id": 3,
"code": "1101",
"name": "Cash on Hand",
"name_ar": "النقدية بالصندوق"
},
"custodian_id": 2,
"custodian": {
"id": 2,
"name": "Mohammed Ali",
"name_ar": "محمد علي"
},
"max_amount": "500.000",
"current_balance": "0.000",
"is_active": true,
"created_at": "2026-02-16T12:00:00.000000Z",
"updated_at": "2026-02-16T12:00:00.000000Z"
}
}Create Receipt (Replenish Fund)
Request POST /api/accounting/petty-cash/1/transactions
{
"type": "receipt",
"amount": "500.000",
"date": "2026-02-16",
"description": "Initial fund replenishment",
"description_ar": "تجديد الصندوق الأولي",
"reference": "REP-001"
}Response 201 Created
{
"data": {
"id": 1,
"petty_cash_id": 1,
"type": "receipt",
"type_label": "Receipt",
"amount": "500.000",
"date": "2026-02-16",
"description": "Initial fund replenishment",
"description_ar": "تجديد الصندوق الأولي",
"reference": "REP-001",
"journal_entry_id": null,
"created_by": 1,
"created_at": "2026-02-16T12:00:00.000000Z"
}
}After this transaction, the fund's current_balance becomes 500.000.
Create Payment (Record Expense)
Request POST /api/accounting/petty-cash/1/transactions
{
"type": "payment",
"amount": "25.500",
"date": "2026-02-17",
"description": "Office supplies - printer paper",
"description_ar": "مستلزمات مكتبية - ورق طابعة",
"reference": "PC-EXP-001"
}Response 201 Created
{
"data": {
"id": 2,
"petty_cash_id": 1,
"type": "payment",
"type_label": "Payment",
"amount": "25.500",
"date": "2026-02-17",
"description": "Office supplies - printer paper",
"description_ar": "مستلزمات مكتبية - ورق طابعة",
"reference": "PC-EXP-001",
"journal_entry_id": null,
"created_by": 1,
"created_at": "2026-02-17T09:00:00.000000Z"
}
}After this transaction, the fund's current_balance becomes 474.500.
List Fund Transactions
Request GET /api/accounting/petty-cash/1/transactions
Response 200 OK
{
"data": [
{
"id": 2,
"type": "payment",
"amount": "25.500",
"date": "2026-02-17",
"description": "مستلزمات مكتبية - ورق طابعة",
"reference": "PC-EXP-001"
},
{
"id": 1,
"type": "receipt",
"amount": "500.000",
"date": "2026-02-16",
"description": "تجديد الصندوق الأولي",
"reference": "REP-001"
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 2 }
}Delete Transaction (Reversal)
Request DELETE /api/accounting/petty-cash/1/transactions/2
Response 200 OK
{
"message": "Deleted"
}After deletion, the balance impact of the deleted transaction is reversed. If a payment of 25.500 is deleted, the fund's current_balance increases by 25.500 back to 500.000.
Business Rules
- GL account required -- Every petty cash fund must be linked to a detail-level GL account (typically "Cash on Hand" or a sub-account).
- Max amount limit -- The
max_amountdefines the ceiling for the fund. A receipt transaction cannot bring the balance above this limit. - Insufficient balance -- A
paymenttransaction is rejected if the amount exceeds thecurrent_balance. The API returns a422error with the message "Insufficient petty cash balance." - Automatic balance update --
receipttransactions increasecurrent_balance;paymenttransactions decrease it. This is handled in a database transaction for consistency. - Deletion reverses balance -- Deleting a transaction reverses its balance impact: deleting a receipt decreases the balance, deleting a payment increases it.
- Custodian assignment -- The
custodian_idlinks to a user who is responsible for the fund. This is for tracking purposes. - Created by tracking -- Each transaction records the
created_byuser for audit trails. - Active funds only -- Transactions can only be created on active petty cash funds.
Workflow
Typical Monthly Cycle
- Month start -- Custodian receives a receipt (replenishment) to bring the fund to its maximum.
- During the month -- Custodian records payment transactions for minor expenses (office supplies, courier fees, small repairs).
- Month end -- Finance reviews all transactions, verifies receipts, and replenishes the fund for the next month.
- Journal entries -- If journal entry generation is enabled, each transaction creates a corresponding entry (debit expense account, credit petty cash account for payments; or debit petty cash account, credit bank account for receipts).