Implementasi Workflow Pengadaan: PR, RFQ, PO, GRN untuk Efisiensi Operasional
T
Kembali ke Blog

Implementasi Workflow Pengadaan: PR, RFQ, PO, GRN untuk Efisiensi Operasional

Tutorial
Tim Pilar Inovasi 24 Jul 2026 5 min baca 2,571 kata 177
Artikel ini membahas implementasi workflow pengadaan PR, RFQ, PO, dan GRN secara praktis untuk meningkatkan efisiensi operasional bisnis Anda. Pelajari cara mengotomatisasi proses pengadaan dan meminimalkan biaya melalui studi kasus nyata dan contoh kode.

Dalam lanskap bisnis yang kompetitif saat ini, efisiensi operasional bukan lagi sekadar pilihan, melainkan sebuah keharusan. Banyak organisasi, mulai dari rumah sakit besar dengan sistem SIMRS kompleks hingga klinik mandiri dan perusahaan manufaktur (seperti ERP Poultry), masih bergulat dengan proses pengadaan yang manual, terfragmentasi, dan rentan kesalahan. Bayangkan, sebuah rumah sakit dengan 200 tempat tidur bisa menghabiskan waktu hingga 5-7 hari hanya untuk memproses satu permintaan pembelian alat kesehatan, melibatkan setidaknya 4-5 departemen. Ini bukan hanya membuang waktu, tetapi juga meningkatkan risiko stok kosong (out-of-stock) yang krusial, menimbulkan biaya operasional tersembunyi, dan berpotensi kehilangan diskon vendor. Data menunjukkan, proses pengadaan yang tidak efisien dapat meningkatkan biaya operasional hingga 10-15% per tahun. Artikel ini akan memandu Anda secara mendalam tentang bagaimana mengimplementasikan workflow pengadaan terintegrasi — mulai dari Purchase Requisition (PR), Request for Quotation (RFQ), Purchase Order (PO), hingga Goods Receipt Note (GRN) — untuk mencapai efisiensi maksimal. Kita akan membahas konsep dasar, detail implementasi teknis dengan stack modern, contoh kode yang dapat dijalankan, skema data, penanganan error, best practices, hingga menjawab pertanyaan umum yang sering muncul.

Konsep Dasar Workflow Pengadaan Terintegrasi

Workflow pengadaan yang terintegrasi adalah serangkaian tahapan sistematis yang dirancang untuk mengelola pembelian barang dan jasa secara efisien, mulai dari identifikasi kebutuhan hingga penerimaan barang. Empat pilar utama dalam workflow ini adalah Purchase Requisition (PR), Request for Quotation (RFQ), Purchase Order (PO), dan Goods Receipt Note (GRN).

Purchase Requisition (PR): Ini adalah dokumen internal yang dibuat oleh departemen atau individu yang membutuhkan barang atau jasa. PR berfungsi sebagai otorisasi awal untuk memulai proses pengadaan. Misalnya, Departemen Farmasi di sebuah SIMRS membutuhkan 500 botol infus NaCl 0.9%. Mereka akan membuat PR yang merinci item, kuantitas, tanggal dibutuhkan, dan tujuan penggunaan. Tanpa sistem terintegrasi, PR seringkali berupa formulir kertas yang harus ditandatangani manual oleh beberapa level manajemen, memakan waktu berhari-hari. Dengan sistem, PR dapat diajukan secara digital, melewati alur persetujuan otomatis berdasarkan matriks yang telah ditentukan, dan mengurangi waktu persetujuan hingga 70%.

Request for Quotation (RFQ): Setelah PR disetujui, jika item yang diminta memerlukan perbandingan harga atau spesifikasi dari beberapa vendor, departemen pengadaan akan mengeluarkan RFQ. RFQ adalah undangan kepada vendor untuk mengajukan penawaran harga dan kondisi pengiriman. Dalam kasus infus NaCl, departemen pengadaan akan mengirimkan RFQ kepada 3-5 vendor farmasi terdaftar. Sistem yang baik memungkinkan pengiriman RFQ otomatis ke portal vendor, memfasilitasi vendor untuk memasukkan penawaran secara langsung, dan memungkinkan perbandingan penawaran (quotation analysis) secara objektif. Ini bisa menghemat biaya pembelian hingga 15% karena adanya kompetisi harga yang transparan.

Purchase Order (PO): Setelah penawaran terbaik dipilih dari RFQ (atau langsung dari PR jika vendor sudah ditentukan), Purchase Order (PO) dibuat dan dikirimkan kepada vendor terpilih. PO adalah dokumen hukum yang mengikat, merinci barang/jasa yang dibeli, kuantitas, harga, syarat pembayaran, dan tanggal pengiriman. Melanjutkan contoh SIMRS, setelah memilih vendor dengan harga terbaik untuk infus NaCl, PO akan diterbitkan ke vendor tersebut. Sistem ERP akan secara otomatis menghasilkan PO dari data RFQ yang disetujui, mencatatnya dalam sistem keuangan, dan mengirimkannya via email atau portal vendor. Ini mengurangi kesalahan entri data dan mempercepat proses pengiriman PO hingga 80%.

Goods Receipt Note (GRN): Tahap terakhir adalah Goods Receipt Note (GRN), atau yang sering disebut juga Receiving Report. GRN dibuat ketika barang atau jasa yang dipesan tiba dan diverifikasi sesuai dengan PO. Dokumen ini mengkonfirmasi penerimaan barang dan memicu pembaruan stok inventori serta proses pembayaran ke vendor. Saat 500 botol infus NaCl tiba di gudang farmasi SIMRS, petugas gudang akan memverifikasi kuantitas, kualitas, dan kesesuaian dengan PO. Setelah diverifikasi, GRN akan dibuat dalam sistem, secara otomatis memperbarui stok farmasi dan memberikan notifikasi ke departemen keuangan untuk memproses pembayaran. Implementasi GRN digital dapat mengurangi selisih stok (stock discrepancies) hingga kurang dari 1% dibandingkan proses manual yang seringkali menghasilkan selisih 3-5%.

Detail Implementasi Teknis dengan Sistem ERP Kustom

Membangun sistem pengadaan terintegrasi memerlukan arsitektur yang kokoh dan pemilihan teknologi yang tepat. Untuk kebutuhan kustom yang spesifik, terutama pada lingkungan dengan kebutuhan integrasi kompleks seperti SIMRS, SIM Klinik, atau ERP Poultry, pendekatan pengembangan kustom seringkali lebih fleksibel dan efisien dibandingkan adopsi solusi off-the-shelf yang mungkin memiliki fitur berlebih atau kurang. Kita akan membahas implementasi dengan fokus pada arsitektur API-centric.

Arsitektur yang direkomendasikan adalah arsitektur mikroservis atau monolitik yang modular, di mana modul pengadaan (Procurement) dapat berinteraksi secara independen dengan modul lain seperti Inventori, Keuangan (Finance), dan Master Data. Untuk backend, penggunaan Laravel versi 11.x sangat disarankan karena ekosistemnya yang matang, dokumentasi yang lengkap, dan dukungan komunitas yang kuat, memungkinkan pengembangan API RESTful yang cepat dan aman. Sebagai database, PostgreSQL versi 16 adalah pilihan yang sangat baik karena skalabilitas, keandalan, dan kemampuannya menangani data relasional maupun JSONB yang kompleks, ideal untuk menyimpan detail pengadaan, riwayat transaksi, dan log audit.

Pada sisi frontend, Vue.js 3 (dengan Composition API dan Vite untuk build tool) dapat digunakan untuk membangun antarmuka pengguna yang responsif dan interaktif, seperti dashboard pengajuan PR, portal vendor untuk RFQ, atau halaman verifikasi GRN. Interaksi antara frontend dan backend dilakukan melalui API RESTful. Misalnya, ketika pengguna mengajukan PR dari antarmuka Vue.js, request akan dikirim ke endpoint API Laravel yang akan memvalidasi data dan menyimpannya ke PostgreSQL.

Integrasi antar modul adalah kunci efisiensi. Setelah PR disetujui dan PO diterbitkan, sistem harus secara otomatis menginformasikan modul inventori tentang perkiraan kedatangan barang. Ketika GRN dibuat, modul inventori harus diperbarui secara real-time untuk mencerminkan penambahan stok. Contoh, jika 500 botol infus NaCl diterima (GRN), data stok di modul inventori akan meningkat 500. Selain itu, modul keuangan akan menerima notifikasi untuk memproses pembayaran setelah GRN disetujui. Untuk integrasi yang lebih kompleks, seperti bridging ke sistem eksternal, kita bisa memanfaatkan message queues seperti RabbitMQ atau Kafka untuk komunikasi asinkron, memastikan ketahanan sistem bahkan jika salah satu layanan mengalami gangguan. Contoh kasus di SIMRS, data pengadaan obat bisa dihubungkan dengan data ketersediaan obat untuk pasien yang kemudian dilaporkan ke sistem SatuSehat (FHIR R4), meskipun secara tidak langsung, untuk pelaporan inventori obat esensial.

Pentingnya manajemen master data yang terpusat tidak bisa diabaikan. Master data item, vendor, dan unit pengukuran harus dikelola di satu tempat (misalnya, modul Master Data) dan digunakan secara konsisten di seluruh modul, termasuk pengadaan. Ini menghindari duplikasi data dan inkonsistensi yang bisa menyebabkan kesalahan fatal. Standar data seperti standar penamaan item atau klasifikasi vendor harus ditetapkan di awal proyek. Referensi dari sistem ERP besar seperti Odoo atau SAP bisa memberikan wawasan tentang struktur data yang robust, meskipun kita membangun solusi kustom.

Contoh Kode Implementasi API untuk Workflow Pengadaan

Berikut adalah contoh implementasi API menggunakan Laravel 11.x untuk mengelola sebagian workflow pengadaan. Kode ini diasumsikan berjalan dalam konteks aplikasi Laravel yang sudah terkonfigurasi.

Contoh 1: Membuat Purchase Requisition (PR) Baru

Kode ini menunjukkan bagaimana sebuah Purchase Requisition dapat diajukan melalui API. Kita akan menggunakan model PurchaseRequisition dan sebuah controller method untuk menangani permintaan POST.

<?phpnamespace App\'Http\Controllers;use App\Models\PurchaseRequisition;use Illuminate\Http\Request;use Illuminate\Support\Facades\Auth;use Illuminate\Support\Facades\Validator;class PurchaseRequisitionController extends Controller{    public function store(Request $request)    {        // Validasi input        $validator = Validator::make($request->all(), [            'item_id' => 'required|string|exists:master_items,id',            'quantity' => 'required|integer|min:1',            'required_date' => 'required|date|after_or_equal:today',            'notes' => 'nullable|string|max:500',        ]);        if ($validator->fails()) {            return response()->json(['message' => 'Validation failed', 'errors' => $validator->errors()], 422);        }        // Asumsi user_id diambil dari user yang sedang login        $user = Auth::user();        if (!$user) {            return response()->json(['message' => 'Unauthorized'], 401);        }        // Generate PR number (contoh sederhana, bisa lebih kompleks)        $prNumber = 'PR' . date('Ymd') . str_pad(PurchaseRequisition::count() + 1, 4, '0', STR_PAD_LEFT);        // Buat PR baru        $pr = PurchaseRequisition::create([            'pr_number' => $prNumber,            'requested_by_user_id' => $user->id,            'item_id' => $request->item_id,            'quantity' => $request->quantity,            'required_date' => $request->required_date,            'notes' => $request->notes,            'status' => 'Pending Approval', // Status awal        ]);        return response()->json(['message' => 'Purchase Requisition created successfully', 'data' => $pr], 201);    }}

Penjelasan: Kode di atas mendefinisikan metode store dalam PurchaseRequisitionController. Metode ini menerima permintaan HTTP POST yang berisi detail PR. Pertama, input divalidasi untuk memastikan semua data yang diperlukan ada dan dalam format yang benar, seperti item_id yang harus ada di tabel master_items dan quantity minimal 1. Jika validasi gagal, respons JSON dengan status 422 (Unprocessable Entity) dikembalikan. Selanjutnya, kode mengasumsikan adanya pengguna yang sudah terautentikasi (Auth::user()) untuk mencatat siapa yang mengajukan PR. Nomor PR (pr_number) dibuat secara sederhana berdasarkan tanggal dan jumlah PR yang sudah ada. Terakhir, sebuah entri baru dibuat di tabel purchase_requisitions dengan status awal 'Pending Approval', dan respons sukses dikirimkan dengan status 201 (Created).

Contoh 2: Memperbarui Status Purchase Order (PO) Setelah GRN

Kode ini menunjukkan bagaimana status Purchase Order dapat diperbarui menjadi 'Received' setelah Goods Receipt Note (GRN) dikonfirmasi, sekaligus memperbarui stok inventori.

<?phpnamespace App\Http\Controllers;use App\Models\PurchaseOrder;use App\Models\Inventory;use Illuminate\Http\Request;use Illuminate\Support\Facades\DB;use Illuminate\Support\Facades\Validator;class GoodsReceiptController extends Controller{    public function confirmReceipt(Request $request, $poId)    {        // Validasi input        $validator = Validator::make($request->all(), [            'received_quantity' => 'required|integer|min:1',            'received_by_user_id' => 'required|string|exists:users,id',            'receipt_date' => 'required|date|before_or_equal:today',        ]);        if ($validator->fails()) {            return response()->json(['message' => 'Validation failed', 'errors' => $validator->errors()], 422);        }        // Cari PO        $po = PurchaseOrder::with('items.item')->find($poId);        if (!$po) {            return response()->json(['message' => 'Purchase Order not found'], 404);        }        if ($po->status === 'Received') {            return response()->json(['message' => 'Purchase Order already received'], 409);        }        // Mulai transaksi database        DB::beginTransaction();        try {            // Update status PO            $po->status = 'Received';            $po->received_at = $request->receipt_date;            $po->received_by_user_id = $request->received_by_user_id;            $po->save();            // Perbarui stok inventori untuk setiap item di PO            foreach ($po->items as $poItem) {                // Asumsi received_quantity berlaku untuk semua item di PO ini,                // atau bisa juga request.received_quantity adalah array per item                // Untuk contoh ini, kita asumsikan 1 item per PO atau jumlah total                $inventory = Inventory::firstOrCreate(                    ['item_id' => $poItem->item_id],                    ['current_stock' => 0, 'warehouse_id' => 'WH001'] // Default warehouse                );                $inventory->current_stock += $poItem->quantity; // Gunakan quantity dari PO item                $inventory->save();            }            DB::commit();            return response()->json(['message' => 'Goods Receipt confirmed, PO status updated, and inventory adjusted', 'data' => $po], 200);        } catch (\Exception $e) {            DB::rollBack();            return response()->json(['message' => 'Failed to confirm goods receipt', 'error' => $e->getMessage()], 500);        }    }}

Penjelasan: Metode confirmReceipt dalam GoodsReceiptController bertanggung jawab untuk memproses konfirmasi penerimaan barang. Metode ini menerima $poId dari URL dan data penerimaan dari body request. Setelah validasi, sistem mencari PurchaseOrder yang sesuai. Jika PO tidak ditemukan atau sudah berstatus 'Received', respons error dikembalikan. Bagian krusialnya adalah penggunaan transaksi database (DB::beginTransaction() dan DB::commit()). Ini memastikan bahwa jika ada bagian dari proses (misalnya, update PO atau update inventori) yang gagal, semua perubahan akan dibatalkan (DB::rollBack()), menjaga integritas data. Status PO diperbarui menjadi 'Received', dan stok inventori untuk setiap item dalam PO ditingkatkan sesuai kuantitas yang dipesan. Ini adalah contoh sederhana, dalam implementasi nyata, received_quantity bisa lebih detail per item, dan mungkin ada tabel GRN terpisah.

Skema Data, Integrasi, dan Penanganan Error

Pengelolaan data yang terstruktur dan penanganan error yang robust adalah fondasi sistem pengadaan yang andal. Mari kita lihat contoh payload data yang realistis dan bagaimana sistem harus merespons terhadap potensi kesalahan.

Contoh Payload JSON untuk Pembuatan Purchase Order (PO)

Ketika frontend atau sistem eksternal ingin membuat PO, mereka akan mengirimkan payload JSON seperti ini ke endpoint API /api/purchase-orders.

{
  "vendor_id": 42,
  "expected_delivery_date": "2024-08-15",
  "items": [
    {
      "product_id": 101,
      "quantity": 50,
      "unit_price": 12500.00
    },
    {
      "product_id": 205,
      "quantity": 20,
      "unit_price": 8750.50
    }
  ],
  "notes": "Pengiriman ke gudang utama lantai 2"
}

Payload di atas mencakup informasi vendor, tanggal perkiraan kedatangan, daftar item beserta kuantitas dan harga satuan, serta catatan tambahan. Sistem harus memvalidasi bahwa vendor_id dan setiap product_id valid, quantity lebih dari nol, dan unit_price tidak negatif. Jika ada item yang tidak ditemukan, respons error yang jelas seperti {"error": "Produk dengan ID 999 tidak ditemukan"} harus dikembalikan dengan status HTTP 422 atau 400.

Tips Praktis Implementasi Workflow Pengadaan yang Efisien

Menerapkan workflow PR, RFQ, PO, hingga GRN bukan sekadar menyalin kode, tetapi membutuhkan perencanaan proses bisnis yang matang. Mulailah dengan memetakan alur approval yang jelas untuk setiap dokumen. Misalnya, PR dengan nilai di bawah batas tertentu bisa disetujui oleh supervisor, sedangkan di atas batas tersebut memerlukan persetujuan manajer atau direktur. Gunakan role-based access control (RBAC) agar setiap pengguna hanya dapat mengakses dan mengubah dokumen sesuai kewenangannya. Selain itu, integrasikan notifikasi otomatis via email atau aplikasi internal ketika status dokumen berubah, sehingga tidak ada permintaan yang tertunda tanpa disadari.

Dari sisi teknis, pastikan setiap transisi status (misalnya dari PR ke RFQ, atau PO ke GRN) tercatat dalam audit trail yang mencatat siapa, kapan, dan apa yang diubah. Ini sangat penting untuk keperluan audit internal maupun eksternal. Gunakan database transaction seperti yang dicontohkan pada confirmReceipt untuk operasi yang melibatkan lebih dari satu tabel, sehingga konsistensi data terjaga. Jangan lupa untuk menerapkan idempotency pada endpoint kritis, misalnya dengan menyertakan request_id unik, agar pengiriman ulang request yang sama tidak menghasilkan duplikasi PO atau GRN.

Terakhir, lakukan pengujian beban dan skenario kegagalan. Simulasikan kasus seperti vendor membatalkan pesanan di tengah jalan, barang datang sebagian, atau harga berubah setelah PO dibuat. Sistem yang baik harus mampu menangani partial receipt dan mencatat selisihnya. Manfaatkan juga fitur soft delete untuk dokumen yang dibatalkan agar data historis tetap tersimpan. Dengan pendekatan ini, efisiensi operasional tidak hanya tercapai dari sisi kecepatan, tetapi juga dari akurasi dan ketertelusuran data.

FAQ

Bagaimana jika barang yang diterima tidak sesuai dengan PO?

Sistem harus menyediakan mekanisme partial receipt atau discrepancy report. Saat konfirmasi GRN, pengguna dapat memasukkan kuantitas yang benar-benar diterima. Jika ada selisih, sistem otomatis membuat catatan ketidaksesuaian dan mengirim notifikasi ke tim pengadaan untuk tindak lanjut, seperti meminta penggantian atau penyesuaian invoice.

Apakah RFQ harus selalu dilakukan sebelum membuat PO?

Tidak selalu. RFQ diperlukan untuk pembelian dengan nilai besar atau ketika ingin membandingkan beberapa vendor. Untuk pembelian rutin dengan vendor tunggal yang sudah terdaftar dalam kontrak harga, PO bisa langsung dibuat berdasarkan PR yang disetujui, dengan catatan tetap mengacu pada harga yang disepakati.

Bagaimana cara menjaga integritas data saat update stok dan PO secara bersamaan?

Gunakan transaksi database (DB::beginTransaction(), DB::commit(), DB::rollBack()) seperti pada contoh confirmReceipt. Pastikan semua operasi yang saling bergantung dibungkus dalam satu transaksi. Selain itu, terapkan penguncian baris (row locking) pada tabel inventori untuk mencegah race condition saat beberapa GRN diproses bersamaan.

Apakah perlu membuat tabel terpisah untuk GRN?

Sangat disarankan. Tabel GRN terpisah memungkinkan pencatatan detail per item, nomor surat jalan, tanggal terima, kondisi barang, dan penerima. Ini memberikan jejak audit yang lebih baik dibandingkan hanya mengubah status PO. Dengan tabel terpisah, Anda juga dapat dengan mudah menghasilkan laporan penerimaan barang per periode.

Kesimpulan

Implementasi workflow pengadaan yang mencakup PR, RFQ, PO, dan GRN membutuhkan kombinasi antara desain proses bisnis yang jelas dan kode yang robust. Mulai dari validasi payload, penggunaan transaksi database, hingga penanganan error yang informatif, setiap komponen berperan penting dalam menciptakan efisiensi operasional. Dengan mengikuti tips praktis dan menjawab FAQ di atas, Anda dapat membangun sistem pengadaan yang tidak hanya cepat, tetapi juga akurat dan dapat diaudit.

Jika Anda ingin memperdalam atau membutuhkan bantuan dalam merancang arsitektur sistem pengadaan yang sesuai dengan kebutuhan bisnis Anda, jangan ragu untuk menghubungi tim konsultan kami. Kami siap membantu Anda dari analisis kebutuhan, desain database, hingga implementasi dan pelatihan pengguna. Konsultasi gratis dapat Anda jadwalkan melalui tautan di situs kami. Wujudkan pengadaan yang lebih efisien dan terkendali bersama kami!

Solusi terkait dari PT Pilar Inovasi Informatika (produk IT Pilar Inovasi): SIMRS SIM Klinik Integrator Bridging SatuSehat. Butuh konsultasi gratis?

Terakhir diperbarui 18 Oct 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!