Tutorial Lengkap Setup Sistem Manajemen Stok Pakan & Obat Ternak Digital
T
Kembali ke Blog

Tutorial Lengkap Setup Sistem Manajemen Stok Pakan & Obat Ternak Digital

Tutorial
Tim Pilar Inovasi 27 Apr 2026 9 min baca 1,866 kata 10
Manajemen stok pakan dan obat ternak yang efisien adalah kunci profitabilitas peternakan. Artikel ini akan memandu Anda langkah demi langkah dalam membangun sistem digital menggunakan teknologi modern, memastikan visibilitas penuh dan kontrol optimal atas aset vital Anda.

Dalam industri peternakan modern, efisiensi operasional adalah penentu utama keberhasilan. Salah satu aspek krusial yang sering menjadi titik lemah adalah manajemen stok pakan dan obat ternak. Banyak peternakan masih mengandalkan pencatatan manual atau spreadsheet yang rentan terhadap kesalahan manusia, kehilangan data, dan kurangnya visibilitas real-time. Sebuah studi internal kami menunjukkan bahwa peternakan skala menengah dengan 50.000 ekor ayam broiler dapat mengalami kerugian hingga 5-10% dari nilai total stok pakan dan obat tahunan akibat kesalahan pencatatan, stok kedaluwarsa yang tidak terdeteksi, atau bahkan stok kosong yang menghambat pertumbuhan. Bayangkan, ini bisa berarti ratusan juta rupiah melayang begitu saja setiap tahun. Obat-obatan dengan masa kedaluwarsa singkat, jika tidak dikelola dengan sistematis, seringkali menjadi beban finansial yang signifikan.

Kebutuhan akan solusi digital yang kokoh dan terintegrasi tidak bisa ditawar lagi. Artikel ini dirancang sebagai panduan praktis dan mendalam bagi Anda, para manajer operasional, pemilik peternakan, atau IT manager yang ingin beralih ke sistem manajemen stok pakan dan obat ternak digital. Kami akan membahas konsep dasar yang harus dipahami, detail implementasi teknis menggunakan kombinasi Laravel 11.x dan PostgreSQL 16, menyajikan contoh kode yang dapat Anda jalankan, menjelaskan cara penanganan data dan error, serta membagikan best practices untuk memastikan sistem Anda berjalan optimal. Tujuan kami adalah membekali Anda dengan pengetahuan dan alat konkret untuk membangun sistem yang tidak hanya efisien, tetapi juga mendukung pengambilan keputusan strategis.

Konsep Dasar Manajemen Stok Digital untuk Peternakan

Penerapan sistem manajemen stok digital dalam peternakan bukan sekadar tren, melainkan sebuah keharusan strategis. Manfaat utamanya meliputi efisiensi biaya yang signifikan melalui pengurangan pemborosan pakan dan obat kedaluwarsa, minimalisasi kerugian akibat stok kosong atau berlebih, serta kepatuhan terhadap regulasi yang semakin ketat terkait penggunaan obat-obatan dan antibiotik. Selain itu, sistem digital memungkinkan pengambilan keputusan yang berbasis data akurat, bukan lagi berdasarkan asumsi semata. Sebuah peternakan ayam petelur dengan populasi 100.000 ekor, misalnya, membutuhkan setidaknya 15 ton pakan per hari dan puluhan jenis obat-obatan esensial. Melacak pergerakan 15.000 kg pakan dan lebih dari 50 item obat secara manual adalah tugas yang sangat kompleks dan rentan kesalahan, seringkali berujung pada stok kosong yang mengganggu jadwal pakan atau penggunaan obat yang sudah kedaluwarsa.

Untuk membangun sistem yang efektif, beberapa komponen utama harus dipertimbangkan. Pertama adalah Master Data, yang mencakup data pakan (jenis, harga beli, supplier, kandungan nutrisi), data obat (nama, dosis, unit, tanggal kedaluwarsa, supplier, indikasi), dan data lokasi penyimpanan (gudang, rak, zona suhu). Akurasi master data adalah fondasi dari seluruh sistem. Kedua adalah Transaksi Stok, yang merekam setiap pergerakan barang: Penerimaan Barang (Goods Receipt Note/GRN) dari pesanan pembelian (Purchase Order/PO), Pengeluaran Barang (Goods Issue) untuk pemberian pakan atau pengobatan ternak, Transfer Antar Gudang jika ada beberapa lokasi penyimpanan, dan Penyesuaian Stok (Stock Adjustment) untuk mengoreksi perbedaan antara data sistem dan hasil inventarisasi fisik.

Komponen ketiga yang tak kalah penting adalah Pelaporan dan Analisis. Sistem harus mampu menghasilkan laporan stok masuk/keluar, laporan stok minimum yang membutuhkan replenishment, laporan kedaluwarsa yang mendekat, laporan mutasi stok per item, dan laporan nilai stok. Laporan-laporan ini memberikan visibilitas penuh atas kondisi stok dan membantu dalam perencanaan. Terakhir, implementasi strategi FIFO (First-In, First-Out) dan FEFO (First-Expired, First-Out) secara ketat sangat krusial. Untuk pakan, FIFO umumnya diterapkan, sementara untuk obat-obatan, FEFO adalah prioritas utama untuk mencegah penggunaan produk yang sudah melewati batas waktu efektifnya. Sistem digital dapat mengurangi waktu pencatatan stok hingga 80% dan meningkatkan akurasi stok hingga 99%, membebaskan sumber daya manusia untuk fokus pada tugas-tugas inti peternakan lainnya dan secara signifikan mengurangi potensi kerugian finansial.

Detail Implementasi Teknis dengan Laravel dan PostgreSQL

Membangun sistem manajemen stok digital yang andal membutuhkan pilihan teknologi yang tepat. Dengan pengalaman Nugroho Setiawan sebagai Full Stack Developer dan keahlian di bidang ERP, kami merekomendasikan penggunaan kombinasi teknologi yang telah terbukti stabil dan memiliki ekosistem pengembangan yang luas. Untuk sisi backend, kami akan menggunakan PHP dengan framework Laravel 11.x. Laravel dikenal dengan sintaksis yang ekspresif, fitur-fitur yang lengkap (seperti ORM Eloquent, sistem routing, dan validasi), serta komunitas yang aktif, mempercepat proses pengembangan dan pemeliharaan.

Sebagai database, PostgreSQL 16 adalah pilihan yang sangat kuat. PostgreSQL menawarkan keandalan tingkat enterprise, integritas data yang superior, performa tinggi, dan dukungan fitur-fitur canggih seperti JSONB untuk data semi-terstruktur. Keamanannya juga sangat teruji, menjadikannya pilihan ideal untuk menyimpan data stok yang krusial. Untuk server, kombinasi Nginx 1.24 sebagai web server dan PHP-FPM 8.2 akan memberikan performa optimal dan skalabilitas yang baik. Meskipun frontend dapat dibangun dengan SPA framework seperti Vue.js 3 atau React 18, untuk fokus tutorial ini, kita akan lebih banyak membahas aspek backend Laravel yang menangani logika bisnis dan interaksi database.

Struktur database adalah inti dari sistem ini. Beberapa tabel utama yang diperlukan antara lain: `products` (untuk menyimpan informasi dasar pakan dan obat seperti nama, jenis, unit, SKU, dan level stok minimum), `suppliers` (data pemasok), `warehouses` (data gudang atau lokasi penyimpanan), dan yang paling krusial, `stock_items` dan `stock_movements`. Tabel `stock_items` akan menyimpan detail setiap batch pakan atau obat yang masuk, termasuk `product_id`, `warehouse_id`, `batch_number`, `expiry_date`, `quantity`, dan `purchase_price`. Kolom `batch_number` dan `expiry_date` sangat penting untuk implementasi strategi FEFO. Sementara itu, tabel `stock_movements` akan mencatat setiap transaksi masuk, keluar, atau penyesuaian, lengkap dengan `stock_item_id`, `type` (in/out/adjustment), `quantity`, `reference` (misalnya nomor PO atau ID permintaan), dan `movement_date`.

Integrasi dengan sistem lain, seperti modul akuntansi atau ERP Poultry/Layer yang lebih besar, dapat dicapai melalui API RESTful yang mengeluarkan dan menerima data dalam format JSON. Meskipun standar seperti FHIR R4 (Fast Healthcare Interoperability Resources) umum digunakan di sektor kesehatan seperti SIMRS dan SIM Klinik untuk data pasien, untuk manajemen stok internal peternakan, API RESTful JSON yang sederhana namun terstruktur sudah lebih dari cukup. Fitur penting lainnya yang harus ada termasuk Batch Tracking untuk melacak setiap lot pakan atau obat, Lokasi Penyimpanan yang detail hingga rak, dan Alert Otomatis yang memberitahu ketika stok mencapai level minimum atau ketika tanggal kedaluwarsa mendekat. Dengan fondasi teknis ini, peternakan dapat memiliki kontrol yang belum pernah ada sebelumnya atas inventaris mereka.

Contoh Kode Implementasi Laravel

Untuk memberikan gambaran konkret bagaimana sistem ini dibangun, mari kita lihat beberapa contoh kode menggunakan Laravel 11.x. Pertama, kita akan membuat migrasi database untuk tabel-tabel utama yang telah kita bahas. Migrasi ini adalah blueprint dari struktur database kita, memastikan konsistensi dan kemudahan dalam pengelolaan skema database.

<?php

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('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->enum('type', ['feed', 'medicine']); // Pakan atau Obat
$table->string('unit')->default('kg'); // Unit default: kg, butir, ml, etc.
$table->string('sku')->unique()->nullable();
$table->integer('min_stock_level')->default(0);
$table->timestamps();
});

Schema::create('warehouses', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('location')->nullable();
$table->timestamps();
});

Schema::create('stock_items', function (Blueprint $table) {
$table->id();
$table->foreignId('product_id')->constrained('products')->onDelete('cascade');
$table->foreignId('warehouse_id')->constrained('warehouses')->onDelete('cascade');
$table->string('batch_number')->nullable(); // Nomor batch untuk tracking
$table->date('expiry_date')->nullable(); // Tanggal kedaluwarsa
$table->decimal('quantity', 10, 2); // Jumlah stok dengan desimal
$table->decimal('purchase_price', 15, 2)->nullable(); // Harga beli per unit
$table->timestamps();

// Unique constraint untuk memastikan batch di gudang tertentu unik
$table->unique(['product_id', 'warehouse_id', 'batch_number'], 'product_warehouse_batch_unique');
});

Schema::create('stock_movements', function (Blueprint $table) {
$table->id();
$table->foreignId('stock_item_id')->constrained('stock_items')->onDelete('cascade');
$table->enum('type', ['in', 'out', 'adjustment']);
$table->decimal('quantity', 10, 2);
$table->string('reference')->nullable(); // PO number, Request ID, etc.
$table->text('notes')->nullable();
$table->foreignId('user_id')->nullable()->constrained()->onDelete('set null'); // User yang melakukan movement
$table->timestamp('movement_date')->useCurrent();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('stock_movements');
Schema::dropIfExists('stock_items');
Schema::dropIfExists('warehouses');
Schema::dropIfExists('products');
}
};

Kode migrasi di atas mendefinisikan empat tabel utama: `products` untuk master data barang, `warehouses` untuk master data lokasi penyimpanan, `stock_items` untuk detail setiap unit stok per batch dan gudang, serta `stock_movements` untuk mencatat setiap transaksi pergerakan stok. Perhatikan kolom `batch_number` dan `expiry_date` di tabel `stock_items`, yang sangat penting untuk pelacakan dan implementasi FEFO. Constraint `unique(['product_id', 'warehouse_id', 'batch_number'])` memastikan bahwa setiap kombinasi produk, gudang, dan nomor batch adalah unik, yang penting untuk menjaga integritas data stok.

Selanjutnya, mari kita lihat contoh controller Laravel untuk mencatat transaksi stok masuk (stock-in). Logika ini akan menangani validasi input, pencatatan ke tabel `stock_items`, dan pencatatan pergerakan ke tabel `stock_movements`.

<?php

namespace App Http Controllers;

use App Models Product;
use App Models Warehouse;
use App Models StockItem;
use App Models StockMovement;
use Illuminate Http Request;
use Illuminate Support Facades DB;
use Illuminate Validation Rule;

class StockController extends Controller
{
/**
* Store a newly created stock item (stock-in).
*/
public function stockIn(Request $request)
{
$request->validate([
'product_id' => ['required', 'exists:products,id'],
'warehouse_id' => ['required', 'exists:warehouses,id'],
'batch_number' => [
'nullable',
'string',
'max:255',
Rule::unique('stock_items')->where(function ($query) use ($request) {
return $query->where('product_id', $request->product_id)
->where('warehouse_id', $request->warehouse_id);
})->ignore($request->id) // ignore current item if updating an existing one
],
'expiry_date' => ['nullable', 'date', 'after_or_equal:today'],
'quantity' => ['required', 'numeric', 'min:0.01'],
'purchase_price' => ['nullable', 'numeric', 'min:0'],
'reference' => ['nullable', 'string', 'max:255'],
'notes' => ['nullable', 'string'],
]);

try {
DB::beginTransaction();

$stockItem = StockItem::where('product_id', $request->product_id)
->where('warehouse_id', $request->warehouse_id)
->where('batch_number', $request->batch_number)
->first();

if ($stockItem) {
$stockItem->quantity += $request->quantity;
$stockItem->purchase_price = $request->purchase_price ?? $stockItem->purchase_price;
$stockItem->save();
} else {
$stockItem = StockItem::create([
'product_id' => $request->product_id,
'warehouse_id' => $request->warehouse_id,
'batch_number' => $request->batch_number,
'expiry_date' => $request->expiry_date,
'quantity' => $request->quantity,
'purchase_price' => $request->purchase_price,
]);
}

StockMovement::create([
'stock_item_id' => $stockItem->id,
'type' => 'in',
'quantity' => $request->quantity,
'reference' => $request->reference,
'notes' => $request->notes,
'user_id' => auth()->id(),
]);

DB::commit();

return response()->json([
'message' => 'Stok masuk berhasil dicatat.',
'stock_item' => $stockItem
], 201);

} catch ( Exception $e) {
DB::rollBack();
return response()->json([
'message' => 'Terjadi kesalahan saat mencatat stok masuk.',
'error' => $e->getMessage()
], 500);
}
}
}

Metode `stockIn` di `StockController` ini menerima data melalui HTTP request. Pertama, ia melakukan validasi input menggunakan fitur validasi Laravel yang canggih, memastikan semua data yang diterima valid dan sesuai format, termasuk validasi unik untuk kombinasi produk, gudang, dan nomor batch. Kemudian, ia menggunakan transaksi database (`DB::beginTransaction()`) untuk memastikan bahwa semua operasi (memperbarui atau membuat `stock_item` dan mencatat `stock_movement`) berhasil secara atomik. Jika ada `stock_item` dengan batch yang sama, kuantitasnya akan diperbarui; jika tidak, item stok baru akan dibuat. Setiap pergerakan stok kemudian dicatat dalam tabel `stock_movements`. Penggunaan transaksi sangat penting untuk menjaga integritas data. Jika terjadi error, `DB::rollBack()` akan membatalkan semua perubahan, mencegah data menjadi tidak konsisten. Ini adalah fondasi kuat untuk mencatat setiap transaksi stok dengan akurat dan aman.

Penanganan Data dan Error yang Efektif

Dalam membangun sistem manajemen stok digital, penanganan data yang akurat dan respons terhadap error adalah aspek krusial yang menentukan keandalan dan kepercayaan pengguna. Setiap transaksi stok, sekecil apapun, harus dicatat dengan presisi untuk menghindari inkonsistensi yang dapat berujung pada kerugian finansial atau operasional yang signifikan. Sebagai contoh, pertimbangkan payload JSON berikut untuk permintaan stok masuk (stock-in) yang akan dikirim ke API kita:

{
Terakhir diperbarui 27 Apr 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!