Tutorial: Setting Up an Efficient Digital System for Livestock Feed and Medicine Stock Management
N
Back to Blog

Tutorial: Setting Up an Efficient Digital System for Livestock Feed and Medicine Stock Management

Tutorial
Nugroho Setiawan · Konsultan IT & Full Stack Developer 18 Jun 2026 9 min baca 2,781 kata 328 views
Optimize your livestock operations with a complete guide to setting up a digital system for managing feed and livestock medicine stock. This article covers step-by-step instructions, from planning to implementation, complete with concrete examples and program code. Significantly improve the efficien

Modern livestock farming faces complex challenges in managing feed and livestock medicine stock. Manual recording is often prone to errors, causing waste, and a lack of real-time visibility into stock availability. This has a direct impact on operational efficiency, livestock health, and the overall profitability of the business. Without an integrated and accurate system, purchasing and distribution decisions for feed and medicine are often not optimal, leading to excess stock at risk of expiration or, conversely, stock shortages that can disrupt vital feeding and treatment schedules. A study published by the Food and Agriculture Organization (FAO) in 2022 highlighted that digitalization of stock management has the potential to reduce operational losses by up to 15-20% in the medium-to-large-scale livestock sector, a significant figure.

This article serves as a practical and in-depth guide for Operations Managers, veterinary clinic owners, or decision-makers in the livestock sector who are determined to implement digital solutions for feed and medicine stock management. With a background of experience in developing Hospital Management Information Systems (SIMRS), livestock-specific Enterprise Resource Planning (ERP) (including Poultry/Layer ERP), as well as various other management systems, we will guide you through concrete steps in building a system that is not only efficient but also scalable and accurate. We will start with basic concepts, then dive into the technical implementation details using modern technologies such as Laravel 11.x and PostgreSQL 16.x, including runnable code examples, error handling scenarios, proven effective best practices, and answering common questions through an FAQ section. Our main goal is to help you achieve higher operational efficiency, reduce the risk of losses, and enable much more accurate and timely data-driven decision-making.

Basic Concepts of Digital Stock Management for Livestock Feed & Medicine

Digitalization of livestock feed and medicine stock management is not just a trend, but a necessity to achieve accuracy, real-time data availability, and superior auditability. Manual systems, although seemingly simple, have inherent limitations such as the potential for human error in recording, difficulty tracking stock in real-time, and complexity in generating comprehensive reports. With a digital system, every transaction is recorded automatically, minimizing errors and providing a clear audit trail.

The main components of a digital stock management system include: Master Data, which covers detailed information about Feed (type, composition, manufacturer), Medicine (name, dosage, form, manufacturer), Supplier (name, contact, purchase history), and Warehouse Location (name, capacity, storage conditions such as refrigerated or room temperature). Then there is Stock Transactions, which record every movement of goods: Receipt (when goods arrive from supplier), Issue (when feed is given or medicine is used), Transfer (between warehouses), and Stock Adjustment (for physical inventory corrections). Finally, Reporting, which provides crucial information such as minimum stock (for automatic purchase triggers), expired stock (for FEFO management), and stock mutations (history of goods movement).

As a concrete example, imagine concentrate feed brand A with batch number X, production date Y, and expiration date Z, stored in the main warehouse. Or antibiotic medicine brand B, batch number P, production date Q, and expiration date R, which requires storage in a cold room. The digital system must be able to track every unit of product down to the batch level, ensuring that feed or medicine that will expire sooner is issued first (FEFO strategy: First-Expired, First-Out). This is a vital practice to reduce losses due to expiration and ensure the quality of the products used.

The benefits of this system are highly diverse: reducing financial losses due to expired feed or medicine, preventing critical stock shortages that can disrupt feeding or treatment programs, optimizing the purchasing process with usage trend analysis, and ensuring compliance with regulations regarding the use of feed and medicine (for example, increasingly strict reporting of antibiotic use). Standardization of product data, such as the use of unique and consistent SKU (Stock Keeping Unit) codes for each item, as well as uniform units of measure (e.g., "kg", "liter", "box", "tablet"), is very important. This standardization is not only for internal accuracy but also crucial for potential integration with other systems in the future, such as Poultry ERP for automatic feed planning or animal health systems for managing medicine prescriptions.

Technical Implementation Details: Building the Foundation with Laravel & PostgreSQL

To build a robust digital stock management system, we need to choose a solid technology foundation. The initial architectural approach can be monolithic, which is faster to implement and easier to manage for medium-scale projects. The backend will be developed using PHP 8.2+ with Laravel Framework 11.x, the latest version offering improved performance, modern features, and a vast ecosystem. As the database, we recommend PostgreSQL 16.x. PostgreSQL is known for its high scalability, superior data integrity, and support for flexible JSONB features, making it very suitable for storing both structured and semi-structured data.

For the frontend side, you have several options: Vue.js 3.x if you want a feature-rich and interactive Single Page Application (SPA), or Livewire 3.x if you want to stay within the Laravel ecosystem and build dynamic interfaces with minimal JavaScript. The development environment can be set up easily using Docker Compose, ensuring consistency among the developer team. For production deployment, Nginx will serve as an efficient web server, managing requests to your Laravel application.

Database design is the backbone of this system. Here is an example of the main tables needed:

  • products: (id, sku, name, description, unit_id, product_type_id) – Stores basic information about feed or medicine.
  • product_types: (id, name: 'pakan', 'obat') – Product category.
  • units: (id, name: 'kg', 'liter', 'box') – Unit of measurement.
  • batches: (id, product_id, batch_number, production_date, expiry_date) – Production batch details.
  • warehouses: (id, name, location) – Storage warehouse information.
  • stock_items: (id, batch_id, warehouse_id, quantity, current_price, created_at, updated_at) – Stock quantity per batch in a specific warehouse.
  • stock_movements: (id, stock_item_id, type: 'in', 'out', 'adjust', quantity, reference, user_id, timestamp) – Stock movement history.

Relationships between tables are very important: stock_items will relate to batches and warehouses, while stock_movements relates to stock_items. This structure allows for highly granular stock tracking, including by expiration date (expiry_date) and batch number (batch_number), which is crucial for implementing the FEFO (First-Expired, First-Out) strategy. Access rights management can be implemented easily using Laravel Spatie Permission, allowing you to define roles such as Admin, Warehouse, and Purchasing with different access rights. Laravel 11.x brings performance improvements and new features such as a more informative `dump()`, while PostgreSQL 16.x offers better query optimization and improved security features, making it a strong choice for the foundation of your system.

Code Examples & Business Logic

To provide a concrete picture of the technical implementation, let's look at some code examples using the Laravel Eloquent ORM. These codes will show how models are defined to represent stock entities and how the business logic for stock receiving is implemented.

Code 1: Eloquent Models and Relationships (Laravel)

Here is an example definition of the StockItem and Batch models. The StockItem model represents the actual stock quantity of a product batch in a specific warehouse, while the Batch model stores detailed information about one production group of a product, including production and expiration dates.

<?phpnamespace App
Models;use Illuminate
Database
Eloquent
Factories
HasFactory;use Illuminate
Database
Eloquent
Model;class StockItem extends Model{    use HasFactory;    protected $fillable = [        'batch_id',        'warehouse_id',        'quantity',        'current_price',    ];    public function batch()    {        return $this->belongsTo(Batch::class);    }    public function warehouse()    {        return $this->belongsTo(Warehouse::class);    }    public function movements()    {        return $this->hasMany(StockMovement::class);    }}
<?phpnamespace App
Models;use Illuminate
Database
Eloquent
Factories
HasFactory;use Illuminate
Database
Eloquent
Model;class Batch extends Model{    use HasFactory;    protected $fillable = [        'product_id',        'batch_number',        'production_date',        'expiry_date',    ];    protected $casts = [        'production_date' => 'date',        'expiry_date' => 'date',    ];    public function product()    {        return $this->belongsTo(Product::class);    }    public function stockItems()    {        return $this->hasMany(StockItem::class);    }}

Code 1 Explanation: The StockItem model represents the physical stock entity in a warehouse, closely tied to a specific product Batch. The belongsTo(Batch::class) relationship ensures each stock item is linked to a unique batch number, enabling detailed tracking of production and expiration dates. Meanwhile, Batch is connected to Product, providing basic information about the feed or medicine. This relationship is fundamental for implementing the FEFO (First-Expired, First-Out) strategy and ensuring stock data accuracy. The use of $casts on the Batch model for production_date and expiry_date ensures that these properties are automatically converted into Carbon date objects, making date manipulation easier.

Code 2: Stock Receiving Logic in Controller (Example StockInController.php)

Here is an example implementation of the store method in a Controller that handles the new stock receiving process. This includes input validation, batch recording, updating or creating stock items, and recording stock movements, all within a database transaction to maintain integrity.

<?phpnamespace App
Http
Controllers;use Illuminate
Http
Request;use Illuminate
Support
Facades
DB;use App
Models
Product;use App
Models
Batch;use App
Models
StockItem;use App
Models
StockMovement;use Illuminate
Validation
ValidationException;class StockInController extends Controller{    public function store(Request $request)    {        $validated = $request->validate([            'product_id' => 'required|exists:products,id',            'warehouse_id' => 'required|exists:warehouses,id',            'batch_number' => 'required|string|max:50',            'production_date' => 'required|date',            'expiry_date' => 'required|date|after_or_equal:production_date',            'quantity' => 'required|integer|min:1',            'price_per_unit' => 'required|numeric|min:0',            'reference' => 'nullable|string|max:255',        ]);        return DB::transaction(function () use ($validated) {            $batch = Batch::firstOrCreate(                [                    'product_id' => $validated['product_id'],                    'batch_number' => $validated['batch_number'],                ],                [                    'production_date' => $validated['production_date'],                    'expiry_date' => $validated['expiry_date'],                ]            );            // If the batch already exists but the expiry date is different, this could be a warning or error depending on policy            if ($batch->wasRecentlyCreated === false && $batch->expiry_date != $validated['expiry_date']) {                // Log warning or throw exception                // throw ValidationException::withMessages(['batch_number' => 'Batch number existing with different expiry date.']);            }            $stockItem = StockItem::firstOrNew(                [                    'batch_id' => $batch->id,                    'warehouse_id' => $validated['warehouse_id'],                ]            );            $stockItem->quantity += $validated['quantity'];            $stockItem->current_price = $validated['price_per_unit']; // Update last price            $stockItem->save();            StockMovement::create([                'stock_item_id' => $stockItem->id,                'type' => 'in',                'quantity' => $validated['quantity'],                'reference' => $validated['reference'] ?? 'New Stock Receipt',                'user_id' => auth()->id(), // Assume there is a logged-in user            ]);            return response()->json(['message' => 'Stock successfully added.', 'stock_item' => $stockItem->load('batch.product')], 201);        });    }}

Code Explanation 2: This store function handles the process of receiving new stock. First, it validates the input using the $request->validate() method to ensure the received data is valid and complete according to the defined rules. Then, it uses DB::transaction to guarantee the atomicity of the operation; if any part of the process fails, all changes made within the transaction will be rolled back, maintaining the integrity of the database data. The Batch::firstOrCreate logic ensures that the same batch is not duplicated based on product_id and batch_number, but still provides flexibility to update information such as the expiration date if the batch already exists. StockItem::firstOrNew will find an existing stock item in a specific warehouse for that batch or create a new entry, then add the received quantity and update the last price. Finally, a StockMovement entry is recorded as history, providing a clear audit trail for every stock receipt. The returned JSON response includes a success message and the details of the stock item that was just processed, with HTTP status 201 Created.

Data & Error Handling

In every digital system, the ability to send and receive data efficiently and handle errors gracefully is key. Below is an example JSON payload for a stock receipt operation and how the Laravel system handles error messages, especially validation.

Example JSON Payload: Feed Stock Receipt

This JSON payload is a representation of the data that will be sent from the frontend to the backend API endpoint to record a feed or medicine stock receipt transaction. Each field has an important role in ensuring stock data is recorded completely and accurately.

Below is an example JSON payload for a feed stock receipt operation:

{
  "product_id": 12,
  "warehouse_id": 3,
  "batch_number": "BATCH-2024-001",
  "expiry_date": "2025-12-31",
  "quantity": 100,
  "unit_price": 25000
}

After the payload is received, Laravel will run validation using FormRequest. If any field does not match—for example, quantity is negative or expiry_date is not a valid date format—the system will return an error response with HTTP status 422 Unprocessable Entity. That response contains an errors structure that maps each field to its error message, so the frontend can display it specifically to the user. For unexpected errors such as database connection failures, the system catches the exception and returns status 500 with a general message, while technical details are logged for debugging purposes without leaking sensitive information.

Practical Tips for Implementing a Stock Management System

Building a digital system for managing livestock feed and medicine stock is not just about writing code, but also about ensuring the system can be relied upon in daily operations. Here are some practical tips you can apply. First, implement layered validation. Perform validation on the frontend to provide quick feedback, but still re-validate on the backend because data from the client can never be fully trusted. Use Laravel's FormRequest feature to centralize validation rules, so the controller code remains clean and easy to maintain.

Second, take advantage of database transactions for operations involving multiple tables. As exemplified in the stock receiving process, use DB::transaction so that every data change is atomic. If a failure occurs midway through the process, all changes will be rolled back, preventing stock data from becoming inconsistent. In addition, consider using database locking such as lockForUpdate when updating stock to avoid race conditions when there are multiple simultaneous requests.

Third, create an informative audit log. Every stock movement—whether receiving, issuing, or adjustment—must be recorded in the StockMovement table with complete information: who performed it, when, how much the quantity was, and for what purpose. This log is very useful for troubleshooting, internal audits, and meeting regulatory requirements. Fourth, design a user-friendly interface. Farms are often operated by staff with limited technical backgrounds, so make sure input forms are simple, provide visual confirmation after a successful action, and provide search and filter features that make it easy to find a specific batch or product.

FAQ

How do you handle expired stock?

You can add an automatic warning feature based on the expiry_date in the batch table. Create a scheduled command in Laravel that runs daily to check for batches that will expire within the next 30 days, then send a notification to the admin. For batches that have already expired, provide a stock adjustment mechanism that records the reduction along with the reason, so that physical stock and system records remain in sync.

Can this system be integrated with a barcode scanner device?

Of course. You can add an input field that accepts barcode scan results on the stock receiving or issuing form. On the frontend side, use an event listener to detect input from the scanner, which generally behaves like a keyboard. Make sure the barcode format used is consistent, for example including product_id and batch_number in a single code, so the system can immediately find the relevant data without manual entry.

How do you ensure the security of stock data from unauthorized access?

Implement role-based access control. Use Laravel Sanctum or Passport for API tokens, and define policies or gates to restrict actions based on role, for example only warehouse admins may perform stock adjustments. In addition, encrypt sensitive data, use HTTPS, and perform regular database backups.

Is it necessary to record minimum and maximum stock?

It is highly recommended. By setting minimum and maximum stock levels per product per warehouse, the system can provide warnings when stock is low or excessive. This helps prevent feed shortages that affect livestock health, while also avoiding stockpiling that increases the risk of expiration and storage costs.

Conclusion

Building an efficient digital system for managing livestock feed and medicine stock requires careful planning, from database design, input validation, use of transactions, to an intuitive user interface. By following best practices such as those outlined above, you can improve stock recording accuracy, reduce the risk of human error, and speed up operational decision-making. Investing in an integrated system will have a positive long-term impact on your farm's productivity.

If you want to implement a similar system or need special adjustments according to your farm's scale, don't hesitate to consult with our team of experts. We are ready to help design, build, and maintain a stock management system that is fit for purpose. Contact us now to get a solution tailored to your business needs.

Terakhir diperbarui 17 Oct 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