Optimalisasi Stok: Konfigurasi Min-Max & Otomatisasi Purchase Request di SIMRS/ERP
N
Kembali ke Blog

Optimalisasi Stok: Konfigurasi Min-Max & Otomatisasi Purchase Request di SIMRS/ERP

Tutorial
Nugroho Setiawan · Konsultan IT & Full Stack Developer 18 Jul 2026 8 min baca 2,428 kata 287 views
Pelajari cara mengimplementasikan konfigurasi min-max stock dan otomatisasi purchase request untuk efisiensi operasional. Artikel ini memandu Anda langkah demi langkah, dari konsep hingga contoh kode nyata, untuk menjaga ketersediaan stok optimal di SIMRS atau ERP Anda.

Manajemen inventori yang tidak efisien adalah salah satu tantangan terbesar yang dihadapi rumah sakit, klinik, dan entitas bisnis lainnya yang mengandalkan ketersediaan stok barang. Overstocking menyebabkan biaya penyimpanan membengkak, risiko kadaluarsa (terutama untuk obat-obatan), dan modal terikat yang bisa digunakan untuk investasi lain. Sebaliknya, understocking dapat mengakibatkan penundaan layanan pasien, kehilangan penjualan, atau bahkan krisis operasional karena ketiadaan barang esensial. Bayangkan sebuah farmasi rumah sakit yang kehabisan obat vital karena proses pemesanan manual yang lambat dan rentan kesalahan. Situasi ini bukan hanya merugikan finansial, tetapi juga berpotensi membahayakan nyawa pasien. Untuk mengatasi masalah krusial ini, konfigurasi min-max stock yang dilengkapi dengan fitur otomatisasi purchase request (permintaan pembelian) menjadi solusi yang sangat efektif. Artikel ini akan memandu Anda secara mendalam, mulai dari konsep dasar, detail implementasi teknis menggunakan teknologi terkini, hingga contoh kode yang dapat dijalankan. Kami juga akan membahas penanganan kasus khusus, best practices, dan menjawab pertanyaan umum untuk memastikan Anda dapat menerapkan sistem ini dengan sukses dan mencapai efisiensi operasional yang optimal.

Konsep Dasar Min-Max Stock dan Otomatisasi Purchase Request

Konfigurasi min-max stock adalah strategi manajemen inventori yang menetapkan dua ambang batas kuantitas untuk setiap item di gudang: level minimum (min_stock) dan level maksimum (max_stock). Level minimum, sering disebut sebagai reorder point, adalah jumlah stok di mana sistem harus memicu tindakan pemesanan ulang. Sementara itu, level maksimum adalah kuantitas target stok yang diinginkan setelah pesanan pembelian diterima, memastikan stok selalu berada dalam rentang yang optimal. Misalnya, untuk obat Paracetamol 500mg, farmasi mungkin menetapkan min_stock 500 box dan max_stock 2000 box. Ini berarti, ketika stok Paracetamol di gudang mencapai atau turun di bawah 500 box, sistem akan secara otomatis memicu permintaan pembelian untuk mengisi kembali stok hingga level maksimum.

Manfaat utama dari penerapan min-max stock sangat signifikan. Pertama, ia secara proaktif mencegah kehabisan stok (stockout), yang sangat krusial di lingkungan kesehatan di mana ketersediaan obat dan alat medis dapat menjadi penentu hidup dan mati. Kedua, ia mengurangi risiko overstocking, yang berarti mengurangi biaya penyimpanan, meminimalkan risiko kerusakan atau kadaluarsa barang, dan membebaskan modal kerja. Ketiga, sistem ini meningkatkan efisiensi operasional dengan mengurangi intervensi manual dalam proses pemesanan ulang, memungkinkan tim operasional untuk fokus pada tugas-tugas yang lebih strategis. Sebuah studi dari APICS (Association for Supply Chain Management) menunjukkan bahwa perusahaan yang mengadopsi praktik manajemen inventori yang terotomatisasi dapat mengurangi biaya persediaan hingga 15-20%.

Otomatisasi purchase request bekerja dengan cara mengintegrasikan logika min-max stock ke dalam sistem informasi manajemen, seperti Sistem Informasi Manajemen Rumah Sakit (SIMRS) atau Enterprise Resource Planning (ERP). Sistem akan secara berkala memindai level stok untuk semua item. Ketika level stok suatu item terdeteksi berada di bawah min_stock yang telah ditetapkan, sistem secara otomatis menghasilkan dokumen purchase request. Kuantitas yang diminta dalam PR ini biasanya dihitung berdasarkan selisih antara max_stock dengan current_stock, atau bisa juga jumlah tetap berdasarkan Economic Order Quantity (EOQ). PR yang dihasilkan kemudian dapat diteruskan untuk persetujuan oleh manajer pembelian sebelum diubah menjadi purchase order (PO) dan dikirim ke supplier.

Faktor-faktor penentu dalam menetapkan nilai min-max stock meliputi: lead time supplier (waktu yang dibutuhkan dari pemesanan hingga barang diterima), tingkat konsumsi rata-rata harian atau bulanan, safety stock (stok pengaman untuk mengantisipasi fluktuasi permintaan atau keterlambatan pengiriman), biaya pemesanan, dan biaya penyimpanan. Sebagai contoh perhitungan sederhana, Reorder Point (Min_Stock) dapat dihitung dengan rumus: (Average Daily Usage × Lead Time dalam hari) + Safety Stock. Jika sebuah rumah sakit rata-rata menggunakan 10 unit obat per hari, lead time supplier adalah 7 hari, dan safety stock yang diinginkan adalah 50 unit, maka Reorder Point-nya adalah (10 × 7) + 50 = 120 unit. Ini berarti ketika stok mencapai 120 unit, sistem harus memicu PR. Max_Stock bisa ditentukan sebagai Reorder Point ditambah kuantitas pesanan ekonomis (misalnya, 200 unit), sehingga Max_Stock = 120 + 200 = 320 unit. Dengan pendekatan ini, manajemen stok menjadi lebih prediktif dan berbasis data.

Detail Implementasi Teknis pada Sistem ERP/SIMRS

Implementasi konfigurasi min-max stock dengan otomatisasi purchase request memerlukan arsitektur sistem yang terintegrasi, melibatkan modul Inventori, Modul Pembelian, dan Modul Master Data Barang. Di tingkat database, kita memerlukan tabel `items` yang menyimpan informasi dasar produk, termasuk kolom `min_stock` dan `max_stock` untuk setiap item. Tabel `stock_levels` akan mencatat kuantitas stok saat ini untuk setiap item di setiap gudang (`item_id`, `current_stock`, `warehouse_id`). Terakhir, tabel `purchase_requests` akan menyimpan semua permintaan pembelian yang dihasilkan, baik secara manual maupun otomatis, dengan kolom seperti `item_id`, `quantity`, `status` (misalnya, 'draft', 'pending_approval', 'approved', 'rejected'), dan `created_at`.

Dalam konteks pengembangan sistem, kita dapat memanfaatkan teknologi modern seperti Laravel 11.x untuk backend aplikasi, yang menyediakan kerangka kerja yang kuat dan fitur scheduler untuk menjalankan tugas otomatis. PostgreSQL 16 adalah pilihan database yang sangat baik karena skalabilitas, keandalan, dan dukungan fitur-fitur canggih untuk manajemen data inventori yang kompleks. Untuk antarmuka pengguna, Vue.js 3 dapat digunakan untuk membangun dashboard yang responsif dan interaktif, meskipun fokus utama implementasi otomatisasi ini berada di sisi backend.

Logika inti dari otomatisasi ini diimplementasikan sebagai scheduled task atau cron job. Di Laravel, ini dapat diatur menggunakan Laravel Scheduler, yang memungkinkan kita mendefinisikan perintah atau job yang akan dijalankan pada interval waktu tertentu (misalnya, setiap 30 menit atau setiap jam). Tugas ini akan melakukan query ke tabel `stock_levels` untuk mengidentifikasi item-item di mana `current_stock` berada di bawah `min_stock` yang tercatat di tabel `items`. Contoh query akan mencari `stock_levels.current_stock < items.min_stock` dengan melakukan join antara kedua tabel berdasarkan `item_id`.

Ketika item yang memenuhi kriteria terdeteksi, sistem akan memicu pembuatan entri baru di tabel `purchase_requests`. Kuantitas yang diminta (`quantity`) dalam PR ini dihitung sebagai `items.max_stock - stock_levels.current_stock`. Status awal PR biasanya 'draft' atau 'pending_approval', menunggu tinjauan dari manajer pembelian. Setelah PR berhasil dibuat, penting untuk mengimplementasikan mekanisme notifikasi. Notifikasi ini dapat berupa email otomatis kepada manajer pembelian, pesan ke aplikasi komunikasi internal (seperti Slack atau Microsoft Teams melalui webhook), atau bahkan integrasi langsung ke dashboard manajer pembelian di dalam sistem ERP/SIMRS itu sendiri. Pentingnya data yang akurat tidak bisa diremehkan; sinkronisasi data stok secara real-time dari setiap transaksi (penjualan, penerimaan barang, transfer antar gudang) adalah kunci keberhasilan sistem ini. Akurasi master data, termasuk min_stock dan max_stock yang selalu terbarui, juga fundamental untuk mencegah anomali dalam proses otomatisasi.

Contoh Kode Implementasi dan Struktur Database

Untuk mengilustrasikan implementasi teknis, mari kita lihat contoh kode dalam konteks Laravel 11.x. Pertama, kita perlu memastikan struktur database yang mendukung. Berikut adalah migrasi Laravel untuk tabel `items` yang mencakup kolom `min_stock` dan `max_stock`, serta tabel `stock_levels` dan `purchase_requests`.

<?phpnamespace DatabaseMigrations;use IlluminateDatabaseMigrationsMigration;use IlluminateDatabaseSchemaBlueprint;use IlluminateSupportFacadesSchema;class CreateInventoryTables extends Migration{    public function up(): void    {        Schema::create('items', function (Blueprint $table) {            $table->id();            $table->string('name');            $table->string('sku')->unique();            $table->integer('min_stock')->default(0);            $table->integer('max_stock')->default(0);            $table->timestamps();        });        Schema::create('warehouses', function (Blueprint $table) {            $table->id();            $table->string('name');            $table->string('location');            $table->timestamps();        });        Schema::create('stock_levels', function (Blueprint $table) {            $table->id();            $table->foreignId('item_id')->constrained('items');            $table->foreignId('warehouse_id')->constrained('warehouses');            $table->integer('current_stock')->default(0);            $table->unique(['item_id', 'warehouse_id']);            $table->timestamps();        });        Schema::create('purchase_requests', function (Blueprint $table) {            $table->id();            $table->string('pr_number')->unique();            $table->foreignId('item_id')->constrained('items');            $table->foreignId('warehouse_id')->constrained('warehouses');            $table->integer('requested_quantity');            $table->enum('status', ['draft', 'pending_approval', 'approved', 'rejected', 'ordered'])->default('draft');            $table->text('notes')->nullable();            $table->timestamps();        });    }    public function down(): void    {        Schema::dropIfExists('purchase_requests');        Schema::dropIfExists('stock_levels');        Schema::dropIfExists('warehouses');        Schema::dropIfExists('items');    }}

Migrasi ini menciptakan tabel `items` dengan kolom `min_stock` dan `max_stock`, tabel `warehouses` untuk mendukung multi-gudang, tabel `stock_levels` untuk mencatat stok per item per gudang, dan tabel `purchase_requests` untuk menyimpan permintaan pembelian. Penting untuk diperhatikan bahwa `min_stock` dan `max_stock` didefinisikan pada level item, sementara `current_stock` berada pada level item per gudang. Ini memungkinkan fleksibilitas dalam mengelola stok di berbagai lokasi.

Selanjutnya, kita akan membuat Artisan Command di Laravel yang bertugas untuk mengecek stok dan membuat purchase request secara otomatis. Command ini kemudian akan dijadwalkan untuk berjalan secara berkala menggunakan Laravel Scheduler.

<?phpnamespace AppConsoleCommands;use AppModelsItem;use AppModelsStockLevel;use AppModelsPurchaseRequest;use IlluminateConsoleCommand;use IlluminateSupportFacadesDB;class AutoGeneratePurchaseRequests extends Command{    protected $signature = 'inventory:auto-pr';    protected $description = 'Automatically generates purchase requests for items below min stock level.';    public function handle(): int    {        $this->info('Starting automatic purchase request generation...');        $lowStockItems = StockLevel::join('items', 'stock_levels.item_id', '=', 'items.id')            ->whereRaw('stock_levels.current_stock < items.min_stock')            ->select('stock_levels.*', 'items.name as item_name', 'items.min_stock', 'items.max_stock')            ->get();        if ($lowStockItems->isEmpty()) {            $this->info('No items found below minimum stock level.');            return Command::SUCCESS;        }        foreach ($lowStockItems as $stockLevel) {            $neededQuantity = $stockLevel->max_stock - $stockLevel->current_stock;            if ($neededQuantity <= 0) {                $this->warn("Item {$stockLevel->item_name} (ID: {$stockLevel->item_id}) has current stock {$stockLevel->current_stock} but max stock {$stockLevel->max_stock}. Skipping PR generation.");                continue;            }            // Check if there's already a pending PR for this item in this warehouse            $existingPendingPR = PurchaseRequest::where('item_id', $stockLevel->item_id)                ->where('warehouse_id', $stockLevel->warehouse_id)                ->whereIn('status', ['draft', 'pending_approval'])                ->first();            if ($existingPendingPR) {                $this->info("Skipping PR for {$stockLevel->item_name} (ID: {$stockLevel->item_id}) in Warehouse {$stockLevel->warehouse_id}: existing pending PR #{$existingPendingPR->pr_number}.");                continue;            }            DB::transaction(function () use ($stockLevel, $neededQuantity) {                $pr = PurchaseRequest::create([                    'pr_number' => 'PR-' . date('YmdHis') . '-' . uniqid(),                    'item_id' => $stockLevel->item_id,                    'warehouse_id' => $stockLevel->warehouse_id,                    'requested_quantity' => $neededQuantity,                    'status' => 'draft',                    'notes' => 'Auto-generated by system due to low stock.'                ]);                $this->info("Generated PR #{$pr->pr_number} for {$neededQuantity} units of {$stockLevel->item_name} (ID: {$stockLevel->item_id}) in Warehouse {$stockLevel->warehouse_id}.");                // Further integration: send notification, log, etc.                // Example: event(new PurchaseRequestCreated($pr));            });        }        $this->info('Automatic purchase request generation finished.');        return Command::SUCCESS;    }}

Kode di atas mendefinisikan sebuah Artisan Command `inventory:auto-pr`. Command ini melakukan join antara `stock_levels` dan `items` untuk menemukan semua item di gudang mana pun yang stoknya di bawah `min_stock`. Untuk setiap item yang ditemukan, ia menghitung kuantitas yang dibutuhkan (`max_stock - current_stock`) dan kemudian membuat entri baru di tabel `purchase_requests`. Penting untuk menambahkan pemeriksaan agar tidak membuat PR ganda untuk item yang sudah memiliki PR yang masih dalam status 'draft' atau 'pending_approval'. Setelah PR dibuat, Anda dapat menambahkan logika untuk mengirim notifikasi atau memicu event lain dalam sistem Anda. Command ini kemudian dijadwalkan di `AppConsoleKernel.php` untuk berjalan, misalnya, setiap jam: `$schedule->command('inventory:auto-pr')->hourly();`.

Penanganan Kasus Khusus dan Integrasi

Dalam implementasi sistem otomatisasi purchase request, tidak jarang kita menemui kasus-kasus khusus yang memerlukan penanganan cermat untuk menjaga keandalan sistem. Salah satu skenario yang mungkin terjadi adalah kegagalan dalam memproses purchase request, meskipun sistem telah berhasil membuatnya. Misalnya, sistem mencoba mengirimkan PR ke API supplier, namun terjadi kegagalan koneksi atau respons error. Berikut adalah contoh payload JSON untuk permintaan pembelian yang realistis, diikuti dengan contoh pesan error dan cara penanganannya.

Sebagai gambaran, payload JSON yang dikirim ke API supplier dapat berbentuk seperti berikut:

{  "pr_number": "PR-2024-000123",  "supplier_code": "SUP-0098",  "warehouse_id": 3,  "items": [    { "item_code": "OBT-001", "qty": 250, "unit": "tablet" }  ],  "requested_by": "system-auto"}

Jika API supplier merespons dengan error, misalnya {"status":"error","message":"Supplier service unavailable"}, maka jangan biarkan PR berstatus 'sent' begitu saja. Simpan respons mentah ke kolom integration_log, ubah status PR menjadi failed_to_send, dan jadwalkan retry dengan exponential backoff. Dengan begitu, tim purchasing dapat menindaklanjuti secara manual tanpa kehilangan jejak data.

Tips Praktis Implementasi Min-Max dan Auto-PR

Pertama, tentukan nilai min_stock dan max_stock berdasarkan data historis pemakaian, bukan sekadar intuisi. Gunakan rata-rata pemakaian harian dikalikan lead time supplier, lalu tambahkan safety stock untuk mengantisipasi fluktuasi. Lakukan review parameter ini secara berkala, misalnya setiap kuartal, karena pola penyakit, musim, dan harga supplier bisa berubah. Parameter yang tidak pernah diperbarui justru menjadi sumber masalah baru: stok menumpuk di satu gudang sementara gudang lain mengalami kekosongan.

Kedua, terapkan idempotensi pada proses auto-PR. Sebelum membuat PR baru, cek apakah sudah ada PR dengan status draft, pending_approval, atau sent untuk kombinasi item dan gudang yang sama. Gunakan database transaction dan unique constraint jika perlu, sehingga command yang berjalan berulang tidak menghasilkan duplikasi. Selain itu, batasi jumlah PR yang dibuat per eksekusi agar tidak membanjiri tim purchasing dalam satu waktu.

Ketiga, sediakan dashboard monitoring yang menampilkan item di bawah min_stock, PR yang gagal terkirim, serta waktu eksekusi command terakhir. Tambahkan alert ke channel internal (email, Slack, atau WhatsApp Gateway) ketika jumlah item kritis melewati ambang tertentu. Dengan visibilitas ini, tim dapat bergerak cepat sebelum kekosongan stok berdampak pada pelayanan pasien atau operasional gudang.

FAQ

Apakah auto-PR harus selalu membuat PR baru setiap kali stok di bawah minimum?

Tidak. Auto-PR sebaiknya hanya membuat PR jika belum ada PR aktif untuk item dan gudang yang sama. Jika sudah ada PR dengan status draft, pending approval, atau sudah dikirim ke supplier, sistem cukup mencatat bahwa item tersebut masih dalam proses pengadaan. Pola ini mencegah duplikasi pesanan dan menjaga hubungan baik dengan supplier.

Bagaimana jika supplier tidak memiliki API untuk menerima purchase request?

Anda dapat menggunakan pendekatan hybrid: sistem tetap membuat PR di database, lalu mengekspor daftar PR ke format CSV atau PDF yang bisa dikirim via email. Alternatif lain adalah menggunakan email parsing atau portal supplier. Yang terpenting, status PR di sistem tetap terupdate secara manual atau semi-otomatis agar tidak ada PR yang menggantung tanpa tindak lanjut.

Seberapa sering command auto-PR sebaiknya dijalankan?

Frekuensi bergantung pada dinamika stok dan lead time supplier. Untuk item cepat habis (fast-moving), eksekusi setiap jam atau beberapa kali sehari sudah memadai. Untuk item lambat (slow-moving), cukup sekali sehari. Pastikan jadwal tidak bertabrakan dengan proses backup atau batch lain agar performa database tetap stabil.

Apakah parameter min-max bisa berbeda antar gudang?

Sangat bisa, bahkan sebaiknya demikian. Gudang dengan volume pasien tinggi atau jarak distribusi jauh memerlukan buffer stok lebih besar. Simpan parameter min-max pada level item-gudang, bukan hanya level item, sehingga perhitungan auto-PR lebih akurat dan tidak menyebabkan overstock di lokasi tertentu.

Kesimpulan

Optimalisasi stok melalui konfigurasi min-max dan otomatisasi purchase request bukan sekadar fitur tambahan, melainkan kebutuhan strategis bagi SIMRS/ERP yang ingin menjaga ketersediaan barang sekaligus efisiensi biaya. Dengan parameter yang tepat, command terjadwal, penanganan error yang rapi, serta monitoring yang berkelanjutan, tim Anda dapat mengurangi pekerjaan manual dan fokus pada keputusan yang lebih bernilai. Jika Anda ingin merancang atau mengaudit alur auto-PR di sistem Anda, tim kami siap membantu. Hubungi kami untuk sesi konsultasi gratis dan dapatkan rekomendasi konfigurasi yang sesuai dengan skala operasional fasilitas kesehatan Anda.

Artikel ini bagian dari edukasi Nugroho Setiawan, konsultan IT Jogja. Solusi terkait: SIMRS SIM Klinik. Butuh konsultasi gratis?

Butuh pendampingan ERP? Lihat layanan Konsultan ERP Jogja — implementasi, integrasi, dan pelatihan ERP di Yogyakarta.

Terakhir diperbarui 02 Nov 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!

Butuh bantuan implementasi?

Saya membantu konsultasi IT & pengembangan aplikasi untuk rumah sakit, klinik, dan bisnis di Yogyakarta (DIY), Magelang, dan sekitarnya.

Produk & Solusi SIMRS ERP Portfolio Konsultasi Gratis