Entry Templates & Recurring Entries
Entry templates capture the structure of frequently used journal entries so they can be reused without re-entering account codes and amounts each time. Recurring entries take this further by scheduling automatic execution of a template on a daily, weekly, monthly, quarterly, or yearly basis.
Purpose
- Define reusable journal entry blueprints with predefined debit/credit lines
- Reduce data entry errors for repetitive transactions (rent, utilities, payroll accruals)
- Schedule recurring entries that automatically generate journal entries on a cadence
- Track execution history including count, last run, and next scheduled run
Entry Template
Entity Attributes
| Field | Type | Description |
|---|---|---|
id | integer | Primary key |
company_id | integer | Owning company |
name | string | Template name (English) |
name_ar | string? | Template name (Arabic) |
description | string? | Description (English) |
description_ar | string? | Description (Arabic) |
entry_type | string? | Categorization label for the template |
is_active | boolean | Whether the template is available for use |
created_at | datetime | Creation timestamp |
updated_at | datetime | Last update timestamp |
Entry Template Line
| Field | Type | Description |
|---|---|---|
id | integer | Primary key |
company_id | integer | Owning company |
entry_template_id | integer | Parent template |
line_number | integer | Display order (auto-assigned) |
account_id | integer | GL account to post to |
debit | decimal(12,3) | Debit amount |
credit | decimal(12,3) | Credit amount |
description | string? | Line description (English) |
description_ar | string? | Line description (Arabic) |
cost_center_id | integer? | Optional cost center |
Recurring Entry
Entity Attributes
| Field | Type | Description |
|---|---|---|
id | integer | Primary key |
company_id | integer | Owning company |
entry_template_id | integer | Template to execute |
name | string | Schedule name (English) |
name_ar | string? | Schedule name (Arabic) |
frequency | enum | daily, weekly, monthly, quarterly, yearly |
start_date | date | When recurring execution begins |
end_date | date? | When recurring execution ends (null = indefinite) |
next_execution_date | date | Next scheduled execution date |
last_executed_at | datetime? | When the entry was last executed |
execution_count | integer | How many times executed so far |
max_executions | integer? | Maximum number of executions (null = unlimited) |
is_active | boolean | Whether the schedule is active |
created_at | datetime | Creation timestamp |
updated_at | datetime | Last update timestamp |
Relationships
API Endpoints
Entry Templates
| Method | Path | Description |
|---|---|---|
GET | /api/accounting/entry-templates | List entry templates (paginated) |
POST | /api/accounting/entry-templates | Create a template with lines |
GET | /api/accounting/entry-templates/{id} | Get a template with lines |
PUT | /api/accounting/entry-templates/{id} | Update a template (lines are replaced if provided) |
DELETE | /api/accounting/entry-templates/{id} | Soft-delete a template |
Recurring Entries
| Method | Path | Description |
|---|---|---|
GET | /api/accounting/recurring-entries | List recurring entry schedules (paginated) |
POST | /api/accounting/recurring-entries | Create a recurring schedule |
GET | /api/accounting/recurring-entries/{id} | Get a recurring entry with template |
PUT | /api/accounting/recurring-entries/{id} | Update schedule parameters |
DELETE | /api/accounting/recurring-entries/{id} | Soft-delete a schedule |
POST | /api/accounting/recurring-entries/{id}/execute | Manually trigger execution |
Request/Response Examples
POST /api/accounting/entry-templates
Create a monthly rent template.
Request
json
{
"name": "Monthly Office Rent",
"name_ar": "إيجار المكتب الشهري",
"description": "Monthly rent payment for headquarters",
"description_ar": "دفع الإيجار الشهري للمقر الرئيسي",
"entry_type": "expense",
"is_active": true,
"lines": [
{
"account_id": 42,
"debit": "1500.000",
"credit": "0.000",
"description": "Rent expense",
"description_ar": "مصروف الإيجار",
"cost_center_id": 3
},
{
"account_id": 15,
"debit": "0.000",
"credit": "1500.000",
"description": "Bank payment",
"description_ar": "الدفع من البنك"
}
]
}Response 201 Created
json
{
"data": {
"id": 5,
"company_id": 1,
"name": "Monthly Office Rent",
"name_ar": "إيجار المكتب الشهري",
"description": "Monthly rent payment for headquarters",
"description_ar": "دفع الإيجار الشهري للمقر الرئيسي",
"entry_type": "expense",
"is_active": true,
"lines": [
{
"id": 9,
"line_number": 1,
"account_id": 42,
"debit": "1500.000",
"credit": "0.000",
"description": "Rent expense",
"description_ar": "مصروف الإيجار",
"cost_center_id": 3
},
{
"id": 10,
"line_number": 2,
"account_id": 15,
"debit": "0.000",
"credit": "1500.000",
"description": "Bank payment",
"description_ar": "الدفع من البنك",
"cost_center_id": null
}
],
"created_at": "2026-02-10T09:00:00.000000Z",
"updated_at": "2026-02-10T09:00:00.000000Z"
}
}POST /api/accounting/recurring-entries
Schedule the rent template for monthly execution.
Request
json
{
"entry_template_id": 5,
"name": "Monthly Rent Schedule",
"name_ar": "جدول الإيجار الشهري",
"frequency": "monthly",
"start_date": "2026-03-01",
"end_date": "2026-12-31",
"max_executions": 10,
"is_active": true
}Response 201 Created
json
{
"data": {
"id": 2,
"company_id": 1,
"entry_template_id": 5,
"name": "Monthly Rent Schedule",
"name_ar": "جدول الإيجار الشهري",
"frequency": "monthly",
"frequency_label": "Monthly",
"start_date": "2026-03-01",
"end_date": "2026-12-31",
"next_execution_date": "2026-03-01",
"last_executed_at": null,
"execution_count": 0,
"max_executions": 10,
"is_active": true,
"template": {
"id": 5,
"name": "Monthly Office Rent"
},
"created_at": "2026-02-10T09:15:00.000000Z",
"updated_at": "2026-02-10T09:15:00.000000Z"
}
}POST /api/accounting/recurring-entries/{id}/execute
Manually trigger execution. Returns the created journal entry.
Response 201 Created
json
{
"data": {
"id": 95,
"entry_number": "JE-2026-0095",
"date": "2026-03-01",
"description": "Monthly Office Rent",
"description_ar": "إيجار المكتب الشهري",
"status": "draft",
"lines": [
{
"account_id": 42,
"debit": "1500.000",
"credit": "0.000"
},
{
"account_id": 15,
"debit": "0.000",
"credit": "1500.000"
}
]
}
}Business Rules
| Rule | Description |
|---|---|
| Balanced lines | Total debits must equal total credits in a template |
| At least two lines | A template must have a minimum of two lines |
| Active template required | Recurring entries can only reference active templates |
next_execution_date auto-set | Set to start_date on creation, advanced after each execution |
| Frequency advancement | After execution: daily +1 day, weekly +7 days, monthly +1 month, quarterly +3 months, yearly +1 year |
| Max executions | If max_executions is set, the schedule deactivates when the count is reached |
| End date | Execution stops when next_execution_date exceeds end_date |
| Line replacement on update | When updating a template with lines, all existing lines are deleted and replaced |
| Inactive templates skip | Inactive recurring entries are skipped during scheduled execution |