Konfigurasi POS Apotek: Batch Tracking & Expired Alert Efektif untuk Keamanan Pasien
N
Kembali ke Blog

Konfigurasi POS Apotek: Batch Tracking & Expired Alert Efektif untuk Keamanan Pasien

Tutorial
Nugroho Setiawan 27 Apr 2026 7 min baca 1,356 kata 1 views
Pelajari panduan mendalam tentang implementasi sistem Point of Sale (POS) apotek yang terintegrasi dengan fitur batch tracking dan notifikasi kedaluwarsa. Artikel ini membahas konsep, implementasi teknis, dan best practices untuk memastikan keamanan obat serta efisiensi operasional.

Dalam ekosistem layanan kesehatan yang dinamis, pengelolaan stok farmasi di apotek menjadi salah satu pilar krusial yang menopang keselamatan pasien dan efisiensi operasional. Tanpa sistem yang robust, risiko pemberian obat kedaluwarsa atau penarikan produk (recall) yang tidak tertangani dapat meningkat drastis, berpotensi membahayakan pasien dan merusak reputasi fasilitas kesehatan. Menurut data dari Badan Pengawas Obat dan Makanan (BPOM) RI, insiden penarikan produk farmasi akibat kualitas suboptimal atau pelanggaran standar distribusi masih sering terjadi, menekankan urgensi sistem kontrol inventori yang presisi. Artikel ini akan memandu Anda melalui konfigurasi Point of Sale (POS) apotek yang tidak hanya memfasilitasi transaksi penjualan, tetapi juga mengintegrasikan fitur esensial seperti pelacakan batch (batch tracking) dan peringatan kedaluwarsa (expired alert). Kami akan membahas konsep dasar, detail implementasi teknis menggunakan teknologi terkini, hingga best practices yang dapat segera Anda terapkan untuk memastikan keamanan obat, kepatuhan regulasi, dan optimalisasi kinerja apotek Anda.

Konsep Dasar Batch Tracking dan Expired Alert dalam POS Apotek

Sistem Point of Sale (POS) modern di apotek harus melampaui fungsi dasar transaksi penjualan. Dua fitur krusial yang wajib diintegrasikan adalah batch tracking dan expired alert. Batch tracking adalah mekanisme pencatatan dan pelacakan setiap unit produk farmasi berdasarkan nomor batch atau lot produksi, tanggal produksi, dan tanggal kedaluwarsa. Setiap obat, vaksin, atau alat kesehatan memiliki nomor batch unik yang dikeluarkan oleh produsen. Contoh konkretnya, jika Anda menerima 1000 tablet Paracetamol 500mg dari distributor, mereka mungkin berasal dari Batch A dengan tanggal kedaluwarsa 31/12/2025 dan Batch B dengan tanggal kedaluwarsa 30/06/2026. Sistem POS harus mampu membedakan dan mencatat kedua batch ini secara terpisah saat penerimaan barang, penyimpanan, hingga penjualan.

Tujuan utama batch tracking adalah untuk memungkinkan penarikan produk (product recall) yang efisien dan akurat. Jika BPOM atau produsen mengeluarkan notifikasi penarikan untuk Batch A Paracetamol karena isu kualitas, apotek dapat dengan cepat mengidentifikasi semua unit dari Batch A yang masih ada di stok dan yang sudah terjual kepada pasien. Ini adalah persyaratan krusial dalam Peraturan Menteri Kesehatan (PMK) No. 73 Tahun 2016 tentang Standar Pelayanan Kefarmasian di Apotek, yang secara implisit menuntut kemampuan pelacakan obat hingga tingkat batch.

Sementara itu, expired alert adalah fitur otomatis yang memberikan notifikasi kepada petugas apotek mengenai produk farmasi yang mendekati atau telah melewati tanggal kedaluwarsa. Sistem ini harus dikonfigurasi untuk memberikan peringatan pada interval waktu tertentu, misalnya 3 bulan, 1 bulan, dan 7 hari sebelum tanggal kedaluwarsa. Notifikasi ini dapat berupa laporan harian, pop-up di layar POS, atau bahkan email otomatis kepada manajer apotek. Contoh sederhana, jika sistem mendeteksi 5 box antibiotik dengan tanggal kedaluwarsa 31/03/2024 dan hari ini adalah 01/01/2024, sistem akan memicu peringatan bahwa obat tersebut akan kedaluwarsa dalam 3 bulan. Dengan demikian, apotek dapat mengambil tindakan proaktif seperti melakukan retur ke distributor, melakukan penjualan dengan diskon khusus (jika diizinkan dan aman), atau memisahkan obat tersebut dari stok aktif untuk dimusnahkan sesuai prosedur.

Integrasi kedua fitur ini bukan sekadar kemewahan, melainkan kebutuhan esensial untuk memitigasi risiko, memastikan kepatuhan regulasi, dan menjaga reputasi apotek. Tanpa keduanya, apotek berisiko tinggi mendistribusikan obat yang tidak layak konsumsi, menghadapi denda atau sanksi dari regulator, serta kehilangan kepercayaan dari pasien. Keamanan pasien adalah prioritas utama, dan batch tracking serta expired alert adalah fondasi teknologi untuk mencapainya.

Detail Implementasi Teknis: Arsitektur dan Teknologi

Implementasi sistem POS apotek dengan batch tracking dan expired alert memerlukan arsitektur basis data yang solid dan pemilihan teknologi yang tepat. Kami merekomendasikan penggunaan tumpukan teknologi modern yang fleksibel dan skalabel. Untuk sisi backend, kombinasi Laravel 11.x sebagai framework PHP dan PostgreSQL 16 sebagai sistem manajemen basis data relasional adalah pilihan yang sangat baik. Laravel menyediakan fondasi MVC (Model-View-Controller) yang kuat, sementara PostgreSQL menawarkan integritas data yang superior, dukungan JSONB untuk data semi-terstruktur, dan performa yang handal untuk kueri kompleks.

Struktur basis data untuk produk farmasi harus mencakup tabel products untuk informasi dasar obat (nama, kekuatan, bentuk sediaan) dan tabel product_batches yang menyimpan detail spesifik setiap batch. Tabel product_batches setidaknya harus memiliki kolom seperti product_id, batch_number, manufacture_date, expiry_date, initial_stock, current_stock, dan unit_cost. Setiap transaksi penjualan atau penerimaan barang akan mengurangi atau menambah current_stock pada batch yang relevan. Penting juga untuk mencatat movement_history dari setiap batch, termasuk kapan dan oleh siapa obat tersebut diterima, dipindahkan, atau dijual.

Untuk fitur expired alert, sebuah cron job atau scheduler harus diimplementasikan pada server. Dalam konteks Laravel, ini dapat dilakukan menggunakan Laravel Scheduler. Kita bisa menjadwalkan perintah harian (misalnya, pada pukul 02:00 pagi) yang akan memindai tabel product_batches dan mengidentifikasi batch yang mendekati atau telah melewati tanggal kedaluwarsa. Kueri SQL akan membandingkan expiry_date dengan tanggal saat ini dan tanggal di masa depan (misalnya, expiry_date BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL '90 days'). Hasil dari kueri ini kemudian dapat diolah untuk memicu notifikasi.

Pada sisi frontend, penggunaan React 18.x atau Vue 3.x akan memberikan pengalaman pengguna yang responsif dan interaktif. Data batch dapat ditampilkan secara jelas saat proses penjualan, memungkinkan kasir memilih batch yang paling awal kedaluwarsa (First Expired, First Out - FEFO) secara manual atau otomatis. Integrasi dengan HAPI FHIR 6.8 atau standar HL7 v2.5.1 dapat dipertimbangkan jika apotek perlu berinteraksi dengan SIMRS lain atau ekosistem SatuSehat/FHIR R4. Misalnya, data stok obat dan riwayat penjualan dapat dipertukarkan sebagai sumber daya MedicationKnowledge atau MedicationRequest untuk integrasi yang lebih luas.

Penting juga untuk memastikan bahwa sistem memiliki mekanisme audit trail yang kuat, mencatat setiap perubahan pada stok batch, termasuk siapa yang melakukan perubahan dan kapan. Ini mendukung kepatuhan terhadap standar akreditasi dan investigasi internal jika terjadi anomali. Pemilihan teknologi yang tepat dan desain basis data yang cermat adalah kunci keberhasilan implementasi fitur-fitur kritis ini.

Contoh Kode Implementasi Backend dan Scheduler

Bagian ini akan menyajikan contoh kode konkret untuk mengimplementasikan logika batch tracking dan expired alert menggunakan Laravel dan PostgreSQL. Kita akan mulai dengan migrasi basis data untuk tabel product_batches dan kemudian contoh kode untuk scheduler yang memicu peringatan kedaluwarsa. Pastikan Anda telah menginstal Laravel 11.x dan mengkonfigurasi koneksi ke PostgreSQL 16.

Pertama, mari buat migrasi untuk tabel product_batches. Tabel ini akan menyimpan detail setiap batch produk farmasi:

<?phpgetenv('app.environment') == 'production';use Illuminate.Database.Migrations.Migration;use Illuminate.Database.Schema.Blueprint;use Illuminate.Support.Facades.Schema;return new class extends Migration{    /**     * Run the migrations.     */    public function up(): void    {        Schema.create('product_batches', function (Blueprint $table) {            $table->id();            $table->foreignId('product_id')->constrained('products')->onDelete('cascade');            $table->string('batch_number')->unique();            $table->date('manufacture_date')->nullable();            $table->date('expiry_date');            $table->integer('initial_stock');            $table->integer('current_stock');            $table->decimal('unit_cost', 10, 2);            $table->timestamps();        });    }    /**     * Reverse the migrations.     */    public function down(): void    {        Schema.dropIfExists('product_batches');    }};

Migrasi di atas menciptakan tabel product_batches dengan kolom product_id (foreign key ke tabel products), batch_number yang unik, tanggal produksi dan kedaluwarsa, stok awal dan stok saat ini, serta biaya per unit. Kolom current_stock akan diperbarui setiap kali ada penjualan atau penerimaan barang. Ini adalah fondasi penting untuk melacak setiap unit obat.

Selanjutnya, kita akan membuat perintah Artisan (command) yang akan dijalankan oleh Laravel Scheduler untuk memeriksa obat yang akan kedaluwarsa. Buat file app/Console/Commands/CheckExpiredProducts.php:

<?phpgetenv('app.environment') == 'production';namespace App.Console.Commands;use Illuminate.Console.Command;use App.Models.ProductBatch;use Carbon.Carbon;use Illuminate.Support.Facades.Log;use Illuminate.Support.Facades.Mail;use App.Mail.ExpiredProductNotification; // Anda perlu membuat Mailable iniclass CheckExpiredProducts extends Command{    /**     * The name and signature of the console command.     *     * @var string     */    protected $signature = 'pharmacy:check-expired';    /**     * The console command description.     *     * @var string     */    protected $description = 'Checks for expired or soon-to-expire products and sends notifications.';    /**     * Execute the console command.     */    public function handle()    {        $today = Carbon::today();        $threeMonthsFromNow = Carbon::today()->addMonths(3);        $oneMonthFromNow = Carbon::today()->addMonth();        $sevenDaysFromNow = Carbon::today()->addDays(7);        // Products expiring within 3 months        $expiringSoon = ProductBatch::where('expiry_date', '>', $today)                                    ->where('expiry_date', '<=', $threeMonthsFromNow)                                    ->where('current_stock', '>', 0)                                    ->with('product')                                    ->get();        // Products expiring within 1 month        $expiringOneMonth = ProductBatch::where('expiry_date', '>', $today)                                        ->where('expiry_date', '<=', $oneMonthFromNow)                                        ->where('current_stock', '>', 0)                                        ->with('product')                                        ->get();        // Products expiring within 7 days        $expiringSevenDays = ProductBatch::where('expiry_date', '>', $today)                                         ->where('expiry_date', '<=', $sevenDaysFromNow)                                         ->where('current_stock', '>', 0)                                         ->with('product')                                         ->get();        // Expired products (already passed expiry date)        $expiredProducts = ProductBatch::where('expiry_date', '<=', $today)                                       ->where('current_stock', '>', 0)                                       ->with('product')                                       ->get();        if ($expiringSoon->isNotEmpty() || $expiredProducts->isNotEmpty()) {            // Contoh: Kirim email notifikasi ke manajer apotek            // Mail::to('manager@apotek.com')->send(new ExpiredProductNotification($expiringSoon, $expiredProducts));            Log::warning(
Terakhir diperbarui 27 Apr 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!