Setelah manajer proyek menyetujui timesheet, sistem mengalikan jam yang disetujui dengan cost rate masing-masing staf yang tersimpan di modul HR, lalu mempostingnya secara otomatis sebagai debit ke akun biaya proyek. Otomatisasi ini menghilangkan perhitungan manual yang rawan kesalahan — yaitu berapa jam yang dihabiskan dan berapa biayanya — yang selama ini menjadi masalah umum di perusahaan jasa profesional. Tidak diperlukan entri data terpisah karena biaya langsung mengalir dari persetujuan ke buku besar.
Dashboard proyek menampilkan indikator lampu lalu lintas berdasarkan seberapa banyak anggaran yang telah terpakai: hijau jika aktual di bawah 75% anggaran, kuning jika 75–90%, dan merah jika di atas 90%. Tampilan visual ini memungkinkan manajer proyek melihat sekilas proyek mana yang cenderung melebihi anggaran tanpa harus membaca angka secara detail. Dashboard diperbarui setiap 15 menit melalui refetchInterval dari React Query.
Sistem mendukung Time and Materials (T&M), Fixed Price, dan Cost Plus. Untuk proyek T&M, draft faktur AR dibuat secara otomatis dari timesheet dan klaim biaya yang telah disetujui. Proyek Fixed Price memicu faktur berdasarkan milestone proyek, sedangkan faktur Cost Plus dihitung sebagai total biaya dikalikan satu ditambah persentase margin yang disepakati. Model penagihan ditetapkan saat proyek dibuat dan menentukan logika pembuatan faktur yang dijalankan.
Cost rate staf berasal dari data gaji dan merupakan informasi penggajian yang sensitif. Menampilkannya di layar timesheet atau laporan proyek akan mengungkapkan detail kompensasi individu kepada pihak yang tidak berhak mengaksesnya. Sistem menyimpan cost rate di modul HR dengan RBAC yang membatasi visibilitas hanya untuk peran Keuangan dan HR, serta laporan proyek hanya menampilkan total biaya proyek tanpa merinci rate individu. Permission khusus cost_rate_visible ditambahkan untuk menegakkan batasan ini.
Setiap entri timesheet mencatat apakah waktu tersebut billable atau non-billable, meskipun dikerjakan dalam proyek klien. Waktu yang dihabiskan untuk rapat internal, penulisan proposal, dan pengerjaan ulang dihitung sebagai non-billable. Rasio jam billable terhadap total jam per manajer proyek adalah salah satu metrik paling mengungkapkan dalam sistem — menunjukkan siapa yang efisien dan siapa yang menghabiskan waktu berlebihan untuk overhead, dan klien selalu terkejut saat pertama kali melihat data tingkat billability mereka yang sebenarnya.
Rata-rata ROI untuk implementasi ERP adalah 52% — artinya setiap dolar yang diinvestasikan menghasilkan $1,52 kembali — dengan sebagian besar perusahaan memulihkan investasi mereka dalam 16 bulan. Untuk bisnis jasa profesional dan konstruksi di Indonesia, project costing sering menjadi modul dengan ROI tercepat: mengetahui persis berapa biaya setiap proyek versus apa yang ditagih dapat mengubah jenis proyek yang tidak menguntungkan menjadi menguntungkan dalam satu kuartal.
Proyek memiliki satu atau lebih baris anggaran, masing-masing terkait dengan kategori biaya: Tenaga Kerja, Perjalanan, Material, Subkontraktor, Lainnya. Setiap baris anggaran memiliki jumlah yang dianggarkan dan opsional kuantitas yang dianggarkan (jam, perjalanan, unit). Modul proyek melacak aktual terhadap setiap baris anggaran saat biaya diposting.
Staf mengirimkan timesheet mingguan melalui UI React sederhana: pilih proyek, pilih tugas, masukkan jam per hari, tambahkan deskripsi. Timesheet masuk ke manajer proyek untuk persetujuan. Setelah disetujui, jam dikalikan dengan cost rate staf (tersimpan di modul HR) untuk menghitung biaya tenaga kerja, yang diposting secara otomatis ke jurnal proyek.
Project Costing Data Flow
┌─────────────────────────────────────────────────────┐
│ COST SOURCES │
│ │
│ Timesheets Expense Claims AP Invoices │
│ (Labor) (Travel/Other) (Materials) │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ hours × cost_rate receipts vendor bills │
└──────────────────────────┬──────────────────────────┘
│ all auto-post to
▼
┌─────────────────────────────────────────────────────┐
│ journal_lines (project_id tagged) │
│ DEBIT Project WIP [cost amount] │
│ CREDIT Accrued Labor [or Expense Payable] │
└──────────────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ Budget vs. Actual Dashboard │
│ │
│ Category Budget Actual Variance Status │
│ Labor 200M 165M +35M 🟢 83% │
│ Travel 15M 18M -3M 🔴 120% │
│ Materials 300M 280M +20M 🟡 93% │
│ Subcontract 50M 40M +10M 🟢 80% │
│ ───────────────────────────────────────────────── │
│ TOTAL 565M 503M +62M 89% │
└─────────────────────────────────────────────────────┘Dari pengalaman saya membangun sistem ERP dalam pekerjaan konsultasi ERP lepas saya: selalu tangkap perbedaan billable/non-billable pada setiap entri timesheet. Waktu yang dihabiskan untuk rapat internal, penulisan proposal, dan pengerjaan ulang adalah non-billable bahkan jika ada di proyek klien. Rasio jam billable vs. total jam per manajer proyek adalah salah satu metrik paling mengungkapkan — menunjukkan siapa yang efisien dan siapa yang menghabiskan waktu berlebihan untuk overhead.
Biaya proyek — perjalanan, akomodasi, hiburan klien — diajukan melalui klaim biaya yang terhubung ke proyek. Workflow klaim biaya mencerminkan proses AP mini: staf mengirimkan bukti (unggah foto), manajer proyek menyetujui, keuangan memverifikasi dan mengganti rugi. Klaim biaya yang disetujui diposting ke buku besar biaya proyek secara otomatis.
Sistem yang saya bangun mendukung tiga model penagihan: Time and Materials (tagih jam aktual × tarif yang disepakati + biaya yang dapat diganti), Fixed Price (penagihan berbasis milestone terlepas dari biaya), dan Cost Plus (biaya + margin yang disepakati%). Untuk proyek T&M, sistem menghasilkan draft faktur AR dari timesheet dan biaya yang disetujui.
-- PostgreSQL: project cost tables
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(20) UNIQUE NOT NULL,
name VARCHAR(200) NOT NULL,
billing_model VARCHAR(20) NOT NULL -- 'TM', 'FIXED', 'COST_PLUS'
);
CREATE TABLE project_budget_lines (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES projects(id),
category VARCHAR(50) NOT NULL, -- 'LABOR','TRAVEL','MATERIALS'
budgeted_amt NUMERIC(15,2) NOT NULL,
budgeted_qty NUMERIC(10,2)
);
-- NestJS: approve timesheet and post cost to ledger
@Transactional()
async approveTimesheet(timesheetId: string) {
const ts = await this.tsRepo.findOneOrFail(timesheetId, {
relations: ['employee', 'project'],
});
const costRate = await this.hrService.getCostRate(ts.employee.id);
const laborCost = ts.hours * costRate;
// Post to journal
await this.journalService.post({
description: `Labor: ${ts.employee.name} - ${ts.project.code}`,
lines: [
{ accountId: ACCOUNTS.PROJECT_WIP, projectId: ts.project.id,
debit: laborCost, credit: 0 },
{ accountId: ACCOUNTS.ACCRUED_LABOR,
debit: 0, credit: laborCost },
],
});
ts.status = 'approved';
await this.tsRepo.save(ts);
}Modul proyek dibangun dengan NestJS untuk API, PostgreSQL untuk data, dan React untuk frontend. Dashboard proyek menggunakan Recharts untuk menampilkan garis tren anggaran vs. aktual dari waktu ke waktu. Saya mengimplementasikan sistem lampu lalu lintas: hijau jika aktual di bawah 75% anggaran, kuning jika 75-90%, merah jika di atas 90%.
Cost rate staf (gaji / jam produktif) adalah informasi penggajian yang sensitif. Jangan tampilkan pada layar timesheet atau dalam laporan yang dapat diakses manajer proyek atau klien. Simpan cost rate di modul HR dengan RBAC yang membatasi akses hanya untuk peran Keuangan dan HR. Laporan proyek harus menampilkan total biaya proyek tanpa mengungkapkan cost rate staf individu.
Laporan profitabilitas menampilkan untuk setiap proyek: nilai kontrak, total biaya (tenaga kerja + langsung), laba kotor, margin laba kotor %, dan status penagihan (berapa banyak yang telah difakturkan vs. dikontrak). Untuk proyek T&M, laporan juga menampilkan realisasi — rasio jam yang ditagih terhadap jam yang timbul.
Modul proyek berintegrasi secara bidireksional dengan modul keuangan: biaya diposting ke buku besar umum saat disetujui (debit WIP Proyek, kredit Tenaga Kerja yang Masih Harus Dibayar), dan pendapatan diposting ketika faktur dibuat. Untuk integrasi penggajian, jam timesheet berfungsi sebagai sumber untuk menghitung penggajian staf berbasis jam atau proyek.