Panduan Lengkap Setup Farmasi Multi-Gudang & Floor Stock di SIMRS
T
Kembali ke Blog

Panduan Lengkap Setup Farmasi Multi-Gudang & Floor Stock di SIMRS

Industri Kesehatan
Tim Pilar Inovasi 17 Sep 2026 7 min baca 1,564 kata 5
Optimalkan pengelolaan stok farmasi rumah sakit Anda dengan panduan mendalam tentang konfigurasi multi-gudang dan floor stock di SIMRS. Pelajari konsep, implementasi teknis, contoh kode, hingga best practices untuk efisiensi dan akurasi yang lebih baik.

Manajemen stok farmasi adalah salah satu tulang punggung operasional rumah sakit yang seringkali menghadapi tantangan kompleks. Bayangkan sebuah rumah sakit tipe B dengan lebih dari 200 tempat tidur, memiliki gudang farmasi pusat, tiga gudang satelit (misalnya, di IGD, Poliklinik Spesialis, dan Rawat Inap), serta puluhan unit floor stock di setiap nurse station. Tanpa sistem yang terintegrasi dan terkonfigurasi dengan baik, risiko seperti obat kadaluarsa yang tidak terdeteksi, stok kosong di unit kritis, atau bahkan kehilangan stok bisa meningkat drastis, menyebabkan kerugian finansial hingga miliaran rupiah per tahun dan menurunkan kualitas pelayanan pasien. Di sinilah peran Sistem Informasi Manajemen Rumah Sakit (SIMRS) menjadi krusial, namun seringkali fitur multi-gudang dan floor stock-nya belum dioptimalkan secara maksimal. Artikel ini akan memandu Anda secara praktis dan mendalam, mulai dari pemahaman konsep dasar hingga implementasi teknis dan strategi terbaik, untuk membangun sistem farmasi multi-gudang yang efisien, akurat, dan sesuai standar di SIMRS Anda.

Konsep Dasar Pengelolaan Farmasi Multi-Gudang dan Floor Stock

Pengelolaan farmasi di rumah sakit modern tidak lagi sesederhana memiliki satu gudang penyimpanan utama. Struktur rumah sakit yang kompleks menuntut adanya sistem distribusi dan penyimpanan yang terdesentralisasi namun tetap terintegrasi. Konsep multi-gudang merujuk pada keberadaan lebih dari satu lokasi penyimpanan fisik obat dan alat kesehatan (alkes) di dalam satu entitas rumah sakit. Ini bisa berupa gudang farmasi pusat sebagai titik penerimaan dan distribusi utama, serta gudang-gudang satelit yang berlokasi strategis di area pelayanan seperti Instalasi Gawat Darurat (IGD), Intensive Care Unit (ICU), atau berbagai poliklinik spesialis. Gudang satelit ini berfungsi untuk mendekatkan stok ke titik pelayanan, mengurangi waktu tunggu, dan meningkatkan responsivitas.

Sementara itu, floor stock adalah sejumlah kecil obat dan alkes yang disimpan langsung di unit perawatan pasien, seperti nurse station di bangsal rawat inap atau ruang tindakan. Tujuan utama floor stock adalah untuk memenuhi kebutuhan medis segera pasien tanpa harus menunggu pengiriman dari gudang farmasi pusat atau satelit. Obat-obatan yang masuk kategori floor stock umumnya adalah obat-obatan esensial, sering digunakan, dan memiliki tingkat konsumsi tinggi. Contohnya, parasetamol, infus NaCl, atau kasa steril. Pengelolaan floor stock memerlukan kontrol yang ketat karena sifatnya yang terdesentralisasi dan seringkali tidak melalui proses resep individual di awal.

Pentingnya akurasi data dan visibilitas stok real-time tidak bisa ditawar dalam model multi-gudang dan floor stock. Bayangkan skenario pergerakan obat: Gudang Utama menerima kiriman obat dari supplier, lalu mendistribusikannya ke Gudang Farmasi IGD. Dari Gudang Farmasi IGD, sejumlah obat dipindahkan ke Floor Stock di nurse station Bedah Umum. Ketika seorang pasien di Bedah Umum memerlukan obat tersebut, perawat mengambilnya dari floor stock dan mencatat pemakaiannya ke sistem. Setiap titik perpindahan ini harus terekam secara akurat di SIMRS. Tanpa sistem yang memadai, perbedaan stok fisik dan sistem bisa mencapai 15-20% dalam sebulan, berujung pada stok kosong mendadak atau penumpukan obat kadaluarsa. Sistem harus mendukung metode pengelolaan stok seperti FIFO (First-In, First-Out) atau FEFO (First-Expired, First-Out) secara otomatis, terutama untuk obat-obatan dengan masa simpan terbatas, guna meminimalkan kerugian akibat kadaluarsa. Regulasi seperti Peraturan Menteri Kesehatan (PMK) No. 72 Tahun 2016 tentang Standar Pelayanan Kefarmasian di Rumah Sakit secara implisit menekankan pentingnya pengelolaan stok yang efisien dan akuntabel, yang hanya bisa dicapai dengan sistem informasi yang terintegrasi dan akurat.

Arsitektur dan Implementasi Teknis di SIMRS

Untuk mengimplementasikan sistem farmasi multi-gudang dan floor stock yang robust, desain arsitektur database menjadi fondasi utama. Kami merekomendasikan penggunaan PostgreSQL 16 sebagai database relasional utama karena dukungan fitur JSONB yang kuat dan performa tinggi untuk data transaksi. Backend dapat dibangun menggunakan Laravel 11.x dengan PHP 8.2+, sementara frontend menggunakan Vue.js 3 atau React 18 untuk pengalaman pengguna yang responsif. Interoperabilitas dapat ditingkatkan dengan mengadopsi standar FHIR R4 untuk pertukaran data, jika diperlukan integrasi dengan sistem eksternal atau EMR.

Struktur tabel database harus dirancang untuk secara eksplisit memodelkan lokasi stok dan pergerakannya. Tabel kunci meliputi:

  • master_lokasi_stok: Menyimpan definisi setiap lokasi penyimpanan. Kolom: id (PK), nama_lokasi (misal: 'Gudang Utama', 'Farmasi IGD', 'Floor ICU'), tipe_lokasi (ENUM: 'Gudang', 'Floor Stock'), is_active (boolean).
  • master_item_farmasi: Katalog semua item farmasi. Kolom: id (PK), kode_item (unik, misal 'PARA500T'), nama_item (misal: 'Paracetamol 500mg Tablet'), satuan_terkecil, harga_beli_rata_rata, harga_jual_standar, is_obat_narkotika (boolean).
  • stok_detail: Menyimpan detail stok per item, per batch, per lokasi. Ini adalah tabel inti untuk ketersediaan stok. Kolom: item_id (FK ke master_item_farmasi), lokasi_id (FK ke master_lokasi_stok), batch_number, expiry_date, jumlah_stok_saat_ini, tanggal_terakhir_update. Komposit unique key: (item_id, lokasi_id, batch_number, expiry_date).
  • transaksi_stok: Log setiap pergerakan stok. Kolom: id (PK), item_id, lokasi_asal_id, lokasi_tujuan_id, jumlah, tipe_transaksi (ENUM: 'Penerimaan', 'Mutasi', 'Pengeluaran Pasien', 'Penyesuaian'), tanggal_transaksi, batch_number, expiry_date, user_id (FK ke user yang melakukan transaksi), keterangan.

Workflow mutasi stok, misalnya dari Gudang Utama ke Floor ICU, akan melibatkan beberapa langkah: (1) Staf farmasi membuat permintaan mutasi di SIMRS. (2) Setelah disetujui, sistem mengurangi jumlah stok di stok_detail Gudang Utama untuk item_id dan batch_number tertentu. (3) Sistem menambah jumlah stok di stok_detail Floor ICU untuk item_id dan batch_number yang sama. (4) Sebuah entri baru ditambahkan ke tabel transaksi_stok dengan tipe_transaksi = 'Mutasi', mencatat lokasi asal dan tujuan. Proses ini harus dilakukan dalam satu transaksi database untuk menjamin integritas data. Penggunaan trigger atau stored procedure di PostgreSQL juga dapat dipertimbangkan untuk otomatisasi dan validasi tambahan, namun umumnya logic bisnis lebih baik ditangani di layer aplikasi (Laravel).

Contoh Kode Implementasi

Berikut adalah contoh implementasi API endpoint di Laravel 11.x untuk melakukan mutasi stok antar lokasi, serta contoh query PostgreSQL 16 untuk melihat laporan stok per lokasi. Kode ini mengasumsikan model Eloquent untuk ItemFarmasi, LokasiStok, StokDetail, dan TransaksiStok sudah didefinisikan.

Code Block 1: Laravel Controller untuk Mutasi Stok

<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\ItemFarmasi; use App\Models\LokasiStok; use App\Models\StokDetail; use App\Models\TransaksiStok; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Validation\ValidationException; class FarmasiStokController extends Controller { public function mutasiStok(Request $request) { $request->validate([ 'item_id' => 'required|exists:master_item_farmasi,id', 'lokasi_asal_id' => 'required|exists:master_lokasi_stok,id', 'lokasi_tujuan_id' => 'required|exists:master_lokasi_stok,id|different:lokasi_asal_id', 'batch_number' => 'required|string|max:50', 'expiry_date' => 'required|date|after_or_equal:today', 'jumlah' => 'required|integer|min:1', 'keterangan' => 'nullable|string|max:255', ]); DB::beginTransaction(); try { $item = ItemFarmasi::findOrFail($request->item_id); $lokasiAsal = LokasiStok::findOrFail($request->lokasi_asal_id); $lokasiTujuan = LokasiStok::findOrFail($request->lokasi_tujuan_id); // Ambil stok detail dari lokasi asal $stokAsal = StokDetail::where('item_id', $item->id) ->where('lokasi_id', $lokasiAsal->id) ->where('batch_number', $request->batch_number) ->where('expiry_date', $request->expiry_date) ->first(); if (!$stokAsal || $stokAsal->jumlah_stok_saat_ini < $request->jumlah) { throw ValidationException::withMessages([ 'jumlah' => 'Stok tidak mencukupi di ' . $lokasiAsal->nama_lokasi . ' untuk item ' . $item->nama_item . ' batch ' . $request->batch_number ]); } // Kurangi stok di lokasi asal $stokAsal->jumlah_stok_saat_ini -= $request->jumlah; $stokAsal->tanggal_terakhir_update = now(); $stokAsal->save(); // Tambah stok di lokasi tujuan (atau buat baru jika belum ada) $stokTujuan = StokDetail::firstOrNew([ 'item_id' => $item->id, 'lokasi_id' => $lokasiTujuan->id, 'batch_number' => $request->batch_number, 'expiry_date' => $request->expiry_date, ]); $stokTujuan->jumlah_stok_saat_ini += $request->jumlah; $stokTujuan->tanggal_terakhir_update = now(); $stokTujuan->save(); // Catat transaksi mutasi TransaksiStok::create([ 'item_id' => $item->id, 'lokasi_asal_id' => $lokasiAsal->id, 'lokasi_tujuan_id' => $lokasiTujuan->id, 'jumlah' => $request->jumlah, 'tipe_transaksi' => 'Mutasi', 'tanggal_transaksi' => now(), 'batch_number' => $request->batch_number, 'expiry_date' => $request->expiry_date, 'user_id' => auth()->id(), // Asumsi user terautentikasi 'keterangan' => $request->keterangan ?? 'Mutasi stok antar lokasi', ]); DB::commit(); return response()->json([ 'message' => 'Mutasi stok berhasil', 'data' => [ 'item' => $item->nama_item, 'dari' => $lokasiAsal->nama_lokasi, 'ke' => $lokasiTujuan->nama_lokasi, 'jumlah' => $request->jumlah, ] ]); } catch (\Exception $e) { DB::rollBack(); throw $e; } } } 

Kode di atas menunjukkan bagaimana validasi input, pengecekan ketersediaan stok, pengurangan stok di lokasi asal, penambahan stok di lokasi tujuan, dan pencatatan transaksi dilakukan dalam satu blok transaksi database. Ini penting untuk menjaga konsistensi data. Jika ada kegagalan di tengah proses, semua perubahan akan dibatalkan.

Code Block 2: Query PostgreSQL untuk Laporan Stok per Lokasi

SELECT ml.nama_lokasi, mi.kode_item, mi.nama_item, sd.batch_number, sd.expiry_date, sd.jumlah_stok_saat_ini FROM stok_detail sd JOIN master_item_farmasi mi ON sd.item_id = mi.id JOIN master_lokasi_stok ml ON sd.lokasi_id = ml.id WHERE sd.jumlah_stok_saat_ini > 0 ORDER BY ml.nama_lokasi, mi.nama_item, sd.expiry_date ASC; 

Query SQL ini mengambil data stok saat ini dari tabel stok_detail, menggabungkannya dengan informasi nama item dari master_item_farmasi dan nama lokasi dari master_lokasi_stok. Hasilnya akan menampilkan daftar stok yang tersedia, dikelompokkan berdasarkan lokasi, nama item, batch number, dan tanggal kadaluarsa, sangat berguna untuk laporan inventori.

Integrasi dan Penanganan Error

Integrasi adalah kunci dalam SIMRS, dan setiap transaksi stok harus dirancang dengan mempertimbangkan skenario ideal dan penanganan kegagalan. Berikut adalah contoh payload JSON untuk mutasi stok yang dikirim ke API yang telah kita buat, serta bagaimana menangani pesan error yang mungkin muncul.

Contoh Payload JSON untuk Mutasi Stok:

{ 
Terakhir diperbarui 17 Sep 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!