# Project Costing and Time Tracking in a Custom ERP: Budgets, Timesheets, and Profitability

> How to build a project costing module with time tracking, cost allocation, budget monitoring, and profitability reporting in a custom ERP using NestJS and PostgreSQL.

URL: https://www.matthewswong.com/en/blog/erp-project-costing-time-tracking/

- Author: Matthews Wong (https://www.matthewswong.com/en/about/)
- Published: 2025-06-10
- Updated: 2025-06-10
- Category: ERP

The average ROI for ERP implementations is 52% — meaning every dollar invested returns $1.52 — with most companies recovering their investment within 16 months. For professional services and construction businesses in Indonesia, project costing is often the module with the fastest ROI: knowing exactly how much each project costs versus what it billed can turn unprofitable project types into profitable ones within a single quarter. As a freelance ERP consultant, I built a project costing module for a consulting firm client that tracks time, expenses, and cost allocations against project budgets in real time. Here's the architecture.

## The Project Budget Structure

A project has one or more budget lines, each tied to a cost category: Labor, Travel, Materials, Subcontractor, Other. Each budget line has a budgeted amount and optionally a budgeted quantity (hours, trips, units). The project module tracks actuals against each budget line as costs are posted. Actuals flow in from three sources: timesheets (labor costs), expense claims (travel, other), and AP invoices tagged to the project (materials, subcontractors). The budget vs. actual comparison is the core output.

### Timesheet Entry and Approval

Staff submit weekly timesheets via a simple React UI: select project, select task (a sub-unit of the project), enter hours per day, add a description. The timesheet goes to the project manager for approval. Once approved, the hours are multiplied by the staff member's cost rate (stored in HR module) to compute the labor cost, which posts automatically to the project's journal as a debit to the project cost account. This fully automated costing eliminates the error-prone manual calculation of 'how many hours did we spend and what did it cost us' that plagues professional services firms.

> From my experience building ERP systems in my freelance ERP consulting work: always capture the billable/non-billable distinction on each timesheet entry. Time spent on internal meetings, proposal writing, and rework is non-billable even if it's on a client project. The billable vs. total hours ratio by project manager is one of the most revealing metrics — it shows who is efficient and who is spending excessive time on overhead. Clients are consistently surprised by their actual billability rates when they first see this data.

## Expense Claims Integration

Project expenses — travel, accommodation, client entertainment — are submitted via expense claims linked to a project. The expense claim workflow mirrors a mini AP process: staff submit receipts (photo upload), project manager approves, finance verifies and reimburses. Approved expense claims post to the project's cost ledger automatically. The project dashboard shows both labor costs (from timesheets) and direct costs (from expenses and AP invoices) in real time.

### Multiple Billing Models

The system I built supports three billing models: Time and Materials (bill actual hours × agreed rate + reimbursable expenses), Fixed Price (milestone-based billing regardless of cost), and Cost Plus (cost + agreed margin%). For T&M projects, the system generates draft AR invoices from approved timesheets and expenses. For Fixed Price, the AR invoice is triggered by project milestones. For Cost Plus, the invoice is the cost total × (1 + margin%). The billing model is set at project creation and determines which invoice generation logic runs.

> **Warning: Cost Rate Confidentiality**

> Staff cost rates (salary / productive hours) are sensitive payroll information. Do not display them on timesheet screens or in reports that project managers or clients can access. Store cost rates in the HR module with RBAC restricting access to Finance and HR roles only. Project reports should show total project cost without revealing individual staff cost rates. I had a client request that caused me to add a cost_rate_visible permission specifically for this — by default, cost rates are visible only to Finance and above.

## How I Approached This

The project module is built with NestJS for the API, PostgreSQL for data, and React for the frontend. The project dashboard uses Recharts to display budget vs. actual trend lines over time. I implemented a traffic-light system: green if actuals are below 75% of budget, amber if 75-90%, red if above 90%. This visual alert system means project managers can see at a glance which projects are trending over budget without reading numbers. The dashboard refreshes every 15 minutes via React Query's refetchInterval.

## Project Profitability Reporting

The profitability report shows for each project: contracted value, total cost (labor + direct), gross profit, gross margin %, and billing status (how much has been invoiced vs. contracted). For T&M projects, the report also shows realization — the ratio of billed hours to incurred hours — which flags scope creep and unbillable work. Management uses this to decide which project types to pursue more aggressively and which to reprice or decline.

## Integration with Finance and Payroll

The project module integrates bidirectionally with the finance module: costs post to the general ledger as they're approved (debit Project WIP, credit Accrued Labor), and revenue posts when invoices are raised. At project completion, the WIP is cleared against revenue. For payroll integration, the timesheet hours serve as the source for computing payroll for hourly or project-basis staff — the payroll module reads approved timesheet hours and generates the payroll computation without manual data re-entry.

## Sources & Further Reading

- Grade App — How ERP Improves Cost Accounting and Project Costing Efficiency — https://grade.app/how-erp-optimizes-cost-accounting-and-project-costing/
- Zconsulto — ERP Implementation Cost Breakdown + Real ROI Examples — https://zconsulto.com/erp-implementation-cost-breakdown-roi-examples/
- NetSuite — How ERP Makes Project Management Easier — https://www.netsuite.com/portal/resource/articles/erp/erp-project-management.shtml

> **Key takeaway:** Project costing only works when timesheets, purchases and revenue all post against the same project code, so profitability can be read per project rather than estimated at year end. For professional services and construction firms that number is the difference between pricing the next job well or badly.

## Source links

- https://grade.app/how-erp-optimizes-cost-accounting-and-project-costing/
- https://zconsulto.com/erp-implementation-cost-breakdown-roi-examples/
- https://www.netsuite.com/portal/resource/articles/erp/erp-project-management.shtml

## FAQ

### Why does the timesheet approval flow automatically post labor costs to the project journal?

Once a project manager approves a timesheet, the system multiplies each staff member's approved hours by their cost rate stored in the HR module and posts the result as a debit to the project cost account. This automation eliminates the error-prone manual calculation of hours spent and their cost that typically plagues professional services firms. No separate data entry step is required — the cost flows directly from approval to the general ledger.

### How does the traffic-light budget monitoring system work?

The project dashboard displays a traffic-light indicator based on how much of the budget has been consumed: green when actuals are below 75% of the budget, amber between 75–90%, and red above 90%. This visual alert lets project managers see at a glance which projects are trending over budget without reading detailed numbers. The dashboard refreshes every 15 minutes via React Query's refetchInterval.

### What are the three billing models supported, and how do they affect invoice generation?

The system supports Time and Materials (T&M), Fixed Price, and Cost Plus. For T&M projects, draft AR invoices are generated automatically from approved timesheets and expense claims. Fixed Price projects trigger invoices on project milestones, while Cost Plus invoices are calculated as total cost multiplied by one plus the agreed margin percentage. The billing model is set at project creation and determines which invoice generation logic runs.

### Why must staff cost rates be kept hidden from project managers and clients?

Staff cost rates are derived from salary data and are sensitive payroll information. Exposing them on timesheet screens or project reports would reveal individual compensation details to people who should not have that access. The system stores cost rates in the HR module with RBAC restricting visibility to Finance and HR roles only, and project reports show total project cost without breaking down individual rates. A dedicated cost_rate_visible permission was added specifically to enforce this boundary.

### How does the billable vs. non-billable distinction help management identify inefficiency?

Every timesheet entry captures whether the time is billable or non-billable, even when worked on a client project. Time spent on internal meetings, proposal writing, and rework counts as non-billable. The ratio of billable to total hours per project manager is one of the most revealing metrics in the system — it surfaces who is efficient and who is spending excessive time on overhead, and clients are consistently surprised by their actual billability rates when they first see this data.

---

- HTML version: https://www.matthewswong.com/en/blog/erp-project-costing-time-tracking/
- Bahasa Indonesia: https://www.matthewswong.com/id/blog/erp-project-costing-time-tracking/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
