Approval Workflows & Audit Trail
In any well-run business, certain actions should not take effect without authorization. A production manager should not be able to approve their own purchase order. A new Bill of Materials should be reviewed before it goes live. A payment batch worth lakhs should require sign-off from a senior manager before funds leave the bank account. Udyamo ERP Lite addresses this need through approval workflows — a formal mechanism for requesting, reviewing, and granting authorization on specific documents.
Equally important is knowing what happened after the fact. When a dispute arises, when an auditor asks questions, or when you simply need to understand how a number changed, you need a complete, tamper-resistant record of who did what, when, and what changed. Udyamo ERP Lite maintains this record through two complementary systems: Activity Logs and Audits.
What You Will Learn
- How the approval workflow operates from submission to resolution
- Which documents can require approval and how the process is configured
- How to submit a document for approval, and how to approve or reject it
- How Activity Logs track user actions across the system
- How the Audits table records detailed before-and-after changes
- How to view the audit trail for specific records
- Why audit trails matter for compliance, dispute resolution, and error detection
Prerequisites
- User accounts and roles configured (covered in Chapter 48: Users, Roles & Permissions)
- Familiarity with the documents that may require approval: Bills of Materials (Chapter 13), Bills (Chapter 28), Payment Batches (Chapter 29)
Approval Workflows
The Concept
An approval workflow adds a checkpoint between document creation and document activation. Instead of a document taking effect immediately when saved, it enters a "pending approval" state and waits for an authorized user to review and approve it. This provides a layer of oversight that prevents unauthorized or erroneous actions from affecting your business operations.
The approval workflow in Udyamo ERP Lite is built on the ApprovalRequest model, which can be linked to any approvable record in the system through a polymorphic association (approvable_type and approvable_id).
ApprovalRequest Structure
| Field | Description |
|---|---|
| approvable_type | The type of document (e.g., Bom, Bill, PaymentBatch) |
| approvable_id | The specific record's ID |
| requested_by_id | The user who submitted the document for approval |
| status | Current state: pending, approved, or rejected |
| notes | Optional notes from the requester or the approver |
| approved_by_id | The user who approved or rejected (null while pending) |
| approved_at | Timestamp of the approval or rejection decision |
Documents That Can Require Approval
The following document types commonly participate in approval workflows:
| Document Type | Why Approval Matters |
|---|---|
| Bill of Materials (BOM) | A BOM defines the material and cost structure of a product. An incorrect BOM leads to wrong material issues, incorrect costing, and production waste. Requiring approval ensures engineering review before a BOM goes into production use. |
| Purchase Bills | Bills represent financial obligations. Approving a bill confirms that the goods or services were received and the amount is correct before payment is processed. |
| Payment Batches | Payment batches authorize bulk payments to vendors. Given the financial magnitude, requiring approval ensures that a senior manager reviews the total outflow before funds are released. |
Tip: Not every document needs an approval workflow. Approval adds a step and introduces a delay. Apply it to high-value, high-risk, or high-impact documents. Routine transactions like individual sales invoices (which are backed by confirmed sales orders) typically do not need a separate approval step.
The Approval Process
The workflow follows a simple three-step lifecycle:
1. Submit for Approval
The user who creates or modifies the document submits it for approval. This creates an ApprovalRequest record with status pending.
2. Review
An authorized user (someone with the manage_approvals permission) reviews the pending request. They can see the document details, the requester, and any notes attached.
3. Approve or Reject
The reviewer either approves the request (status changes to approved, the document becomes active) or rejects it (status changes to rejected, with notes explaining the reason). The approved_by_id and approved_at fields are populated at this point.

Step-by-step: Submitting a Document for Approval
- Open the document that requires approval (e.g., a new Bill of Materials).
- After filling in all required fields, click Submit for Approval (instead of the standard Save or Activate button).
- Optionally add notes explaining the context (e.g., "New BOM for 20mm MS Flange — replaces old BOM with updated material quantities based on revised drawings").
- The document status changes to Pending Approval. It is visible but not yet active in production workflows.
- The approver is notified of the pending request.
Step-by-step: Approving a Request
- Navigate to Approval Requests from the sidebar (or access via notifications).
- The list shows all pending approval requests with document type, requester, date, and notes.
- Click on a pending request to review the underlying document.
- Review the document details carefully. For a BOM, verify the components, quantities, and unit costs. For a payment batch, verify the vendor list and amounts.
- If satisfied, click Approve. Optionally add notes (e.g., "Reviewed against engineering drawing REV-3. Quantities confirmed.").
- If the document has issues, click Reject. Add notes explaining what needs to change (e.g., "Quantity for item MS-PIPE-25MM appears incorrect — should be 4 units per assembly, not 40. Please verify and resubmit.").
- The requester is notified of the decision.
Warning: Once approved, the document becomes active. For BOMs, this means production orders can now be created using the approved BOM. For payment batches, this means the payments can be processed. Review carefully before approving.
Step-by-step: Handling a Rejection
- The requester receives notification that their submission was rejected, along with the reviewer's notes.
- Open the rejected document.
- Make the corrections indicated in the rejection notes.
- Submit for approval again. This creates a new ApprovalRequest record — the history of the previous rejection is preserved.
Audit Trail
Why Audit Trails Matter
An audit trail is a chronological record of every significant action taken in the system. It answers four critical questions:
- Who performed the action?
- What action was performed?
- When was it performed?
- What changed as a result?
Audit trails serve multiple purposes:
| Purpose | Example |
|---|---|
| Regulatory compliance | Auditors under the Companies Act, 2013 require evidence that financial records have not been tampered with. The audit trail provides this evidence. |
| Dispute resolution | A vendor claims they were quoted a different price. The audit trail on the purchase order shows exactly when the price was changed, by whom, and from what value to what value. |
| Error detection | An account balance looks wrong. The audit trail on the account reveals that someone changed the account type from "Expense" to "Asset" last week, causing misclassification. |
| Internal control | Management can monitor whether the segregation of duties is being followed — is the same person creating and approving records? |
Activity Logs
The ActivityLog model tracks user actions at a high level. Every significant action — creating a record, updating a record, approving a request, generating a report — is logged.
ActivityLog structure:
| Field | Description |
|---|---|
| user_id | The user who performed the action |
| action | Description of the action (e.g., "created", "updated", "deleted", "approved") |
| trackable_type | The type of record affected (e.g., "Invoice", "ProductionOrder", "JournalEntry") |
| trackable_id | The specific record's ID |
| metadata | Additional context stored as JSONB (e.g., IP address, browser, specific field changes) |
| organization_id | The organization this log belongs to |
| created_at | When the action occurred |
Activity Logs provide a quick, scannable history of system usage. They answer "what happened" without necessarily providing the granular detail of what specific values changed.
Audits (Detailed Change Tracking)
The Audits table provides a more detailed record, capturing the exact before-and-after values for every change to an auditable record.
Audits structure:
| Field | Description |
|---|---|
| auditable_type | The type of record (e.g., "Account", "Invoice", "Payment") |
| auditable_id | The specific record's ID |
| user_id | The user who made the change |
| action | The type of change: create, update, or destroy |
| audited_changes | JSONB field containing the changes — for an update, this shows the old and new values of each modified field |
| version | Sequential version number for this record (version 1 = creation, version 2 = first update, etc.) |
| remote_address | IP address of the user when the change was made |
| created_at | Timestamp of the change |
Example of audited_changes for an update:
When a user changes the billing amount on a purchase bill from 45,000 to 48,500, the audited_changes field records:
{
"amount": [45000.0, 48500.0]
}
The first value in the array is the old value; the second is the new value. This provides an unambiguous, tamper-resistant record of exactly what changed.
Viewing Audit History
Udyamo ERP Lite provides audit trail access on key records. The URL pattern follows the format /<resource>/:id/audit_trail.
Step-by-step: Viewing the audit trail for an account
- Navigate to Accounting > Chart of Accounts.
- Click on the account you want to inspect.
- On the account detail page, click Audit Trail (or navigate to the audit trail tab).
- The system displays a chronological list of all changes to this account, including:
- Who made each change
- When the change was made
- What was changed (with before and after values)
- The IP address of the user
Records with accessible audit trails:
| Record Type | How to Access |
|---|---|
| Accounts | Account detail page > Audit Trail |
| Payments | Payment detail page > Audit Trail |
| Bank Accounts | Bank account detail page > Audit Trail |
| Invoices | Invoice detail page > Audit Trail |
| Bills | Bill detail page > Audit Trail |

Tip: When your statutory auditor visits for the annual audit, the audit trail is your first line of defence against any question about financial record integrity. Being able to show exactly who changed what, when, and why (via the metadata and notes) demonstrates strong internal controls and saves time during the audit process.
Activity Logs vs. Audits: When to Use Which
| Aspect | Activity Logs | Audits |
|---|---|---|
| Level of detail | High-level (action + record reference) | Granular (field-by-field before/after values) |
| Primary use | Monitoring user activity, identifying unusual patterns | Investigating specific changes, regulatory compliance |
| Typical user | Manager, system administrator | Auditor, accountant, compliance officer |
| Example question | "How many records did this user create last week?" | "Who changed the amount on invoice INV-2025-0089, and what was the original value?" |
Tips & Best Practices
Tip: Review pending approval requests daily. A backlog of pending approvals delays operations — production cannot start without an approved BOM, and vendors cannot be paid without approved payment batches. Assign backup approvers for when the primary approver is unavailable.
Tip: Use rejection notes constructively. A rejection without explanation frustrates the requester and wastes time. Always explain what is wrong and what needs to change. This turns the approval process into a quality control mechanism rather than a bottleneck.
Tip: Periodically review Activity Logs for unusual patterns — a user creating an unusually high number of journal entries, or modifications happening outside business hours. These patterns may indicate errors or, in rare cases, unauthorized activity.
Warning: Audit records are system-generated and should not be modifiable by any user. If your auditor asks whether the audit trail can be altered, the answer is no — these records are created automatically by the system and are not exposed for editing.
Quick Reference
| Concept | Location | Key Points |
|---|---|---|
| Approval Requests | Sidebar > Approval Requests | List of pending, approved, and rejected requests |
| Submit for Approval | On the document form (BOM, Bill, Payment Batch) | Creates a pending ApprovalRequest |
| Approve / Reject | Approval request detail page | Changes status; populates approved_by and approved_at |
| Activity Logs | System-wide (accessed by administrators) | High-level tracking of user actions |
| Audits | Record-specific (e.g., accounts/:id/audit_trail) | Granular change history with before/after values |
| audited_changes | JSONB field on Audits table | Stores old and new values for each modified field |
| Version | On Audits table | Sequential version number tracking the history of a record |
| Compliance | Companies Act, 2013 | Requires maintenance of audit trails for financial records |