This guide describes the Validate APM Document Signature Hashes feature, which allows users to verify that signature hashes on APM documents (PDFs) match the system’s approval records.
APM documents (memos, ARFs, activities, etc.) show a verification hash next to each signatory on the PDF. This hash is generated from the document ID, signatory staff ID, and approval date/time. The signature verification tool lets you:
All verification methods submit via AJAX, show a progress indicator, and display results in a single modal with an option to print.
/signature-verify).Document numbers follow the format:
AU/CDC/{division}/IM/{type}/{counter}
Examples:
AU/CDC/SDI/IM/SM/011 — Single Memo (SM), counter 011AU/CDC/DHIS/IM/SPM/002 — Special Memo (SPM)AU/CDC/DHIS/IM/NT/001 — Non-Travel Memo (NT)AU/CDC/DHIS/IM/ARF/003 — Request for ARF (ARF)AU/CDC/DHIS/IM/CR/001 — Change Request (CR)AU/CDC/DHIS/IM/SR/001 — Service Request (SR)AU/CDC/DHIS/IM/QM/001 — Quarterly Matrix activity (QM)The type segment identifies the document table (activities, special_memos, non_travel_memos, request_arfs, change_request, service_requests). Lookup uses this to query the correct table when the full document number is provided.
1. Click Validate uploaded document.
2. Choose a PDF (max 10 MB). Only PDF is accepted.
3. Click Validate document.
- File is processed in memory/temp and not saved on the server.
- Text is extracted (requires smalot/pdfparser). If the library is missing, run: composer require smalot/pdfparser.
- Extracted document numbers (e.g. AU/CDC/.../IM/SM/011) and hashes (16-character hex after “Verify Hash:” or “Hash:”) are validated.
- If multiple document numbers are found (e.g. ARF + parent memo), the system finds all matching documents and merges their signatories. A hash is considered valid if it matches any signatory from any of those documents.
- Final state: Valid or Not valid (valid if at least one extracted hash matched).
- Document number(s) and hash(es) found in the PDF.
- For each matched document: type, document number, activity title (if present), creator, division, date created.
- Hash validation table (each hash: Valid / No match, and signatory if matched).
- Full signatories table with hashes (and document column when multiple documents).
1. Enter document number (e.g. AU/CDC/SDI/IM/SM/011).
2. Enter year of creation (e.g. 2026).
3. Click Look up.
1. Enter the verification hash (e.g. from a PDF).
2. Enter document number.
3. Optionally enter year (if omitted, all years are searched).
4. Click Verify hash.
The verification hash is computed in App\Helpers\PrintHelper::generateVerificationHash():
created_at).strtoupper(substr(md5(sha1($itemId . $staffId . $dateTime)), 0, 16)).Y-m-d H:i:s (e.g. 2026-02-11 01:35:18).The same logic is used when generating hashes on PDFs (e.g. in PrintHelper::renderBudgetSignature() and related views), so hashes on the PDF and in the verification tool stay in sync.
approval_trails (morph) and activity_approval_trails, so hashes from the main signature section and the budget section of the PDF can both be validated.approval_trails morph table.Metadata shown for each document includes activity title when the model has it (e.g. Activity, ChangeRequest, NonTravelMemo, SpecialMemo, RequestARF).
ARFs and service requests can carry both their own document number and the parent memo’s document number. When validating an uploaded PDF:
GET /signature-verify (index), POST /signature-verify/lookup, POST /signature-verify/verify, POST /signature-verify/validate-upload.App\Http\Controllers\SignatureVerificationController.smalot/pdfparser; optional. Without it, upload validation fails with a message to install the package.Accept: application/json / AJAX and return a unified structure (document, metadata, signatories, hash_validations, etc.) for the modal.| Issue | What to do |
|-------|------------|
| “Could not read the PDF” on upload | Ensure the PDF is not encrypted and is a valid PDF. Run composer require smalot/pdfparser if the library is missing. |
| No signatories / no hashes on lookup | For activities, both approval_trails and activity_approval_trails are used; if both are empty, there are no signatories. For other types, check that the document has approval trail records. |
| Hash does not match | Confirm the hash is exactly 16 hex characters and matches the document number. Check that the PDF was generated by this system and not edited. |
| Modal not centered | The view includes centering classes and CSS for #verificationResultModal; if your theme overrides .modal, adjust the modal container styles. |
Related documentation