This guide describes supplementary service requests in APM (UI label; stored as child SRs via parent_service_request_id): requests that cover the remaining memo balance after a parent service request has requested less than the full original memo budget.
When a parent service request’s Total Requested Funds is less than the Original Memo Budget, funds may still be needed for the same approved memo (DSA, imprest, tickets, etc.). A child service request:
source_type, source_id, activity, fund type, division).original_total_budget − new_total_budget on the parent at the time the child is created.service_requests.parent_service_request_id.Only one direct child may exist per service request (root or nested). Nested children are allowed: a child SR may have its own child when it still has remaining balance (original_total_budget − new_total_budget on that SR).
| Key | Group | Type | Default |
|-----|-------|------|---------|
| allow_child_service_requests | service_requests | boolean | 1 (on) |
UI: App Settings → Service requests (/system-settings).
When the setting is off, the Create supplementary request button is hidden and new supplementary SRs cannot be created.
Seed / deploy:
php artisan db:seed --class=SystemSettingsSeeder
On the parent service request detail page (GET /service-requests/{id}), the button is shown only when all of the following are true:
| Rule | Implementation |
|------|----------------|
| Feature enabled | ServiceRequest::childRequestsEnabled() → allow_child_service_requests |
| Parent still has unrequested balance | remainingMemoBalanceForChild() > 0 on the SR you are creating from (root or child) |
| Parent has a linked source memo | source_type and source_id set |
| Parent memo within activity period | parentSourceMemoIsWithinActivityPeriod() — today is between the source memo’s date_from and date_to (or payload dates for other memos); non-travel memos are exempt |
| Remaining memo balance > 0 | remainingMemoBalanceForChild() > 0 (parent original_total_budget > parent new_total_budget) |
| No child already exists | childServiceRequests()->exists() is false |
| User permitted | userCanCreateChildRequest() — draft/returned: is_with_creator_generic; approved/pending/in progress: parent staff_id, responsible_person_id, or focal_person_id |
Create URL: GET /service-requests/create?parent_service_request_id={parentId}
If the parent is not eligible, create redirects back with an error message.
/service-requests/333).Supplementary requests show a plain-text note after the Subject on the memorandum PDF (no border): supplementary funds, the balance remaining on the previous service request, and the previous SR document number (falls back to request_number, then SR #id only if both are missing). The subject line shows SUPPLEMENTARY SERVICE REQUEST.
At the end of the service request PDF (same approach as Change Request Memo / Original Approval Memo embeds), approved previous service requests are included before the Original Approval Memo:
document_number, then request_number, then SR #id only if both are missingOnly records with overall_status = approved are embedded. Pending/draft parents are omitted from the attachment block.
| Field (child) | Meaning |
|---------------|---------|
| original_total_budget | Set to parent’s remaining balance at child creation (fixed cap for that child) |
| new_total_budget | Sum of requested costs on the child; must be ≤ cap |
Parent remaining balance (at create time; same formula for root or nested parent):
remaining = max(0, parent.original_total_budget − parent.new_total_budget)
On a root SR, original_total_budget is the full memo budget. On a child SR, original_total_budget is the cap allocated when that child was created; any further child uses what that SR did not request.
Validation:
new_total_budget > cap; copies parent source fields and sets parent_service_request_id.original_total_budget (the cap at creation).The child does not change the parent’s totals; it only consumes the “shortfall” the parent did not request.
Migration: 2026_05_20_100000_add_parent_service_request_id_to_service_requests_table.php
| Column | Type | Notes |
|--------|------|--------|
| parent_service_request_id | nullable unsignedBigInteger FK → service_requests.id | Indexed; null = parent or standalone SR |
php artisan migrate
| Area | Location |
|------|----------|
| Model helpers | App\Models\ServiceRequest — parentServiceRequest(), childServiceRequests(), isChildRequest(), childRequestsEnabled(), remainingMemoBalanceForChild(), parentSourceMemoIsWithinActivityPeriod(), canCreateChildRequest(), userCanCreateChildRequest() |
| HTTP | App\Http\Controllers\ServiceRequestController — create, store, update, show, PDF build |
| Views | resources/views/service-requests/show.blade.php, create.blade.php, partials/child-request-banner.blade.php, print.php |
| Setting seed | database/seeders/SystemSettingsSeeder.php |
| Settings group label | App\Http\Controllers\SystemSettingsController — group service_requests |
change_request_id with parent_service_request_id on the same create flow.| Issue | Check |
|-------|--------|
| Button missing | Setting off, balance fully requested, child exists, today outside parent memo activity dates (non-travel exempt), or user not permitted |
| Cannot open create link | Parent failed userCanCreateChildRequest() (redirect with flash error) |
| Save rejected over cap | Reduce line items; cap is shown in banner and budget summary |
| Setting not in UI | Run SystemSettingsSeeder or add key manually under group service_requests, type boolean |