DEV Community

top_distribution6432
top_distribution6432

Posted on • Originally published at laravel.setup.com

Laravel setp up sample

PART 1: Setup
bashcomposer create-project laravel/laravel medicine-system
cd medicine-system
Create database in phpMyAdmin:
medicine_db
Edit .env:
DB_DATABASE=medicine_db
DB_USERNAME=root
DB_PASSWORD=
Install Breeze:
bashcomposer require laravel/breeze --dev
php artisan breeze:install blade
php artisan migrate
npm install
npm run build
Install Bootstrap UI and PDF only:
bashnpm uninstall tailwindcss postcss autoprefixer

composer require aldhix/breeze-bootstrap-ui
php artisan breeze-bootstrap-ui:install --force
composer require barryvdh/laravel-dompdf
npm install
npm run build
Create files:
bashphp artisan make:model Medicine -mcr
php artisan make:controller ReportController

PART 2: Migration
Open database/migrations/xxxx_create_medicines_table.php:
php<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::create('medicines', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('generic_name');
$table->string('category');
$table->integer('quantity');
$table->date('expiration_date');
$table->decimal('price', 8, 2);
$table->string('status')->default('available');
$table->timestamps();
});
}

public function down(): void
{
    Schema::dropIfExists('medicines');
}
Enter fullscreen mode Exit fullscreen mode

};
Run:
bashphp artisan migrate

PART 3: Model
Open app/Models/Medicine.php:
php<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Medicine extends Model
{
protected $fillable = [
'name',
'generic_name',
'category',
'quantity',
'expiration_date',
'price',
'status',
];

protected $casts = [
    'expiration_date' => 'date',
];

public function isExpired(): bool
{
    return $this->expiration_date->isPast();
}

public function isLowStock(): bool
{
    return $this->quantity <= 10;
}
Enter fullscreen mode Exit fullscreen mode

}

PART 4: Routes
Open routes/web.php and use this:
php<?php

use App\Http\Controllers\MedicineController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\ReportController;
use Illuminate\Support\Facades\Route;

Route::middleware('auth')->group(function () {
Route::get('/', function () {
return redirect()->route('medicines.index');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->name('dashboard');

Route::resource('medicines', MedicineController::class);

Route::get('/reports', [ReportController::class, 'index'])->name('reports.index');
Route::get('/reports/pdf', [ReportController::class, 'exportPdf'])->name('reports.pdf');
Route::get('/reports/csv', [ReportController::class, 'exportCsv'])->name('reports.csv');

Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
Enter fullscreen mode Exit fullscreen mode

});

require DIR.'/auth.php';

PART 5: Medicine Controller
Open app/Http/Controllers/MedicineController.php:
php<?php

namespace App\Http\Controllers;

use App\Models\Medicine;
use Illuminate\Http\Request;

class MedicineController extends Controller
{
public function index()
{
$medicines = Medicine::latest()->paginate(10);
return view('medicines.index', compact('medicines'));
}

public function create()
{
    return view('medicines.create');
}

public function store(Request $request)
{
    $request->validate([
        'name'            => 'required|string|max:255',
        'generic_name'    => 'required|string|max:255',
        'category'        => 'required|string',
        'quantity'        => 'required|integer|min:0',
        'expiration_date' => 'required|date',
        'price'           => 'required|numeric|min:0',
        'status'          => 'required|string',
    ]);

    Medicine::create($request->all());

    return redirect()->route('medicines.index')
        ->with('success', 'Medicine added successfully!');
}

public function show(Medicine $medicine)
{
    return view('medicines.show', compact('medicine'));
}

public function edit(Medicine $medicine)
{
    return view('medicines.edit', compact('medicine'));
}

public function update(Request $request, Medicine $medicine)
{
    $request->validate([
        'name'            => 'required|string|max:255',
        'generic_name'    => 'required|string|max:255',
        'category'        => 'required|string',
        'quantity'        => 'required|integer|min:0',
        'expiration_date' => 'required|date',
        'price'           => 'required|numeric|min:0',
        'status'          => 'required|string',
    ]);

    $medicine->update($request->all());

    return redirect()->route('medicines.index')
        ->with('success', 'Medicine updated successfully!');
}

public function destroy(Medicine $medicine)
{
    $medicine->delete();

    return redirect()->route('medicines.index')
        ->with('success', 'Medicine deleted successfully!');
}
Enter fullscreen mode Exit fullscreen mode

}

PART 6: Report Controller
Open app/Http/Controllers/ReportController.php:
php<?php

namespace App\Http\Controllers;

use App\Models\Medicine;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;

class ReportController extends Controller
{
public function index(Request $request)
{
$query = Medicine::query();

    if ($request->filled('category')) {
        $query->where('category', $request->category);
    }

    if ($request->filled('expiration_status')) {
        if ($request->expiration_status === 'expired') {
            $query->where('expiration_date', '<', now());
        } elseif ($request->expiration_status === 'not_expired') {
            $query->where('expiration_date', '>=', now());
        }
    }

    $medicines  = $query->get();
    $categories = Medicine::distinct()->orderBy('category')->pluck('category');

    return view('reports.index', compact('medicines', 'categories'));
}

public function exportPdf(Request $request)
{
    $query = Medicine::query();

    if ($request->filled('category')) {
        $query->where('category', $request->category);
    }

    if ($request->filled('expiration_status')) {
        if ($request->expiration_status === 'expired') {
            $query->where('expiration_date', '<', now());
        } elseif ($request->expiration_status === 'not_expired') {
            $query->where('expiration_date', '>=', now());
        }
    }

    $medicines = $query->get();

    return Pdf::loadView('reports.pdf', compact('medicines'))
        ->download('medicine-report.pdf');
}

public function exportCsv(Request $request)
{
    $query = Medicine::query();

    if ($request->filled('category')) {
        $query->where('category', $request->category);
    }

    if ($request->filled('expiration_status')) {
        if ($request->expiration_status === 'expired') {
            $query->where('expiration_date', '<', now());
        } elseif ($request->expiration_status === 'not_expired') {
            $query->where('expiration_date', '>=', now());
        }
    }

    $medicines = $query->get();

    $headers = [
        'Content-Type'        => 'text/csv',
        'Content-Disposition' => 'attachment; filename="medicine-report.csv"',
    ];

    $callback = function () use ($medicines) {
        $file = fopen('php://output', 'w');

        fputcsv($file, ['Name', 'Generic Name', 'Category', 'Quantity', 'Expiration Date', 'Price', 'Status']);

        foreach ($medicines as $medicine) {
            fputcsv($file, [
                $medicine->name,
                $medicine->generic_name,
                $medicine->category,
                $medicine->quantity,
                $medicine->expiration_date->format('Y-m-d'),
                $medicine->price,
                $medicine->status,
            ]);
        }

        fclose($file);
    };

    return response()->stream($callback, 200, $headers);
}
Enter fullscreen mode Exit fullscreen mode

}

PART 7: Layout Fix
Open resources/views/layouts/app.blade.php.
Find this:
html
{{ $slot }}

Replace with this:
html
@hasSection('content')
@yield('content')
@else
{{ $slot ?? '' }}
@endif

PART 8: Navigation
Open resources/views/layouts/navigation.blade.php.
Inside the left-side nav area, add or fix these links:
html

  • <li class="nav-item">
        <x-nav-link :active="request()->routeIs('reports.*')"
            :href="route('reports.index')">
            Reports
        </x-nav-link>
    </li>
    

PART 9: Blade Views
medicines/index.blade.php
Create/open resources/views/medicines/index.blade.php:
blade@extends('layouts.app')

@section('content')

    <h2>Medicine Inventory</h2>
    <a href="{{%20route('medicines.create')%20}}">+ Add Medicine</a>


@if(session('success'))
    {{ session('success') }}
@endif

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Generic Name</th>
            <th>Category</th>
            <th>Quantity</th>
            <th>Expiration Date</th>
            <th>Price</th>
            <th>Status</th>
            <th>Actions</th>
        </tr>
    </thead>

    <tbody>
        @forelse($medicines as $medicine)
            <tr>
                <td>{{ $medicine-&gt;name }}</td>
                <td>{{ $medicine-&gt;generic_name }}</td>
                <td>{{ $medicine-&gt;category }}</td>
                <td>{{ $medicine-&gt;quantity }}</td>
                <td>{{ $medicine-&gt;expiration_date-&gt;format('M d, Y') }}</td>
                <td>₱{{ number_format($medicine-&gt;price, 2) }}</td>
                <td>
                    @if($medicine-&gt;status === 'available')
                        <span>Available</span>
                    @elseif($medicine-&gt;status === 'low_stock')
                        <span>Low Stock</span>
                    @else
                        <span>Out of Stock</span>
                    @endif
                </td>
                <td>
                    <a href="{{%20route('medicines.show',%20$medicine)%20}}">View</a>
                    <a href="{{%20route('medicines.edit',%20$medicine)%20}}">Edit</a>


                        @csrf
                        @method('DELETE')
                        Delete

                </td>
            </tr>
        @empty
            <tr>
                <td colspan="8">No medicines yet. Add one!</td>
            </tr>
        @endforelse
    </tbody>
</table>

{{ $medicines-&gt;links() }}
Enter fullscreen mode Exit fullscreen mode

@endsection

medicines/create.blade.php
Create/open resources/views/medicines/create.blade.php:
blade@extends('layouts.app')

@section('content')

<h2>Add New Medicine</h2>

@if($errors-&gt;any())

        @foreach($errors-&gt;all() as $error)
            {{ $error }}
        @endforeach

@endif


    @csrf


        Medicine Name




        Generic Name




        Category

            -- Select Category --
            @foreach(['Analgesic', 'Antibiotic', 'Antacid', 'Antihistamine', 'Vitamin', 'Other'] as $cat)

                    {{ $cat }}

            @endforeach




        Quantity




        Expiration Date




        Price (₱)




        Status

            Available
            Low Stock
            Out of Stock



    Add Medicine
    <a href="{{%20route('medicines.index')%20}}">Cancel</a>
Enter fullscreen mode Exit fullscreen mode

@endsection

medicines/edit.blade.php
Create/open resources/views/medicines/edit.blade.php:
blade@extends('layouts.app')

@section('content')

<h2>Edit - {{ $medicine-&gt;name }}</h2>

@if($errors-&gt;any())

        @foreach($errors-&gt;all() as $error)
            {{ $error }}
        @endforeach

@endif


    @csrf
    @method('PUT')


        Medicine Name




        Generic Name




        Category

            @foreach(['Analgesic', 'Antibiotic', 'Antacid', 'Antihistamine', 'Vitamin', 'Other'] as $cat)
                category) == $cat ? 'selected' : '' }}&gt;
                    {{ $cat }}

            @endforeach




        Quantity




        Expiration Date




        Price (₱)




        Status

            status) == 'available'    ? 'selected' : '' }}&gt;Available
            status) == 'low_stock'    ? 'selected' : '' }}&gt;Low Stock
            status) == 'out_of_stock' ? 'selected' : '' }}&gt;Out of Stock



    Update Medicine
    <a href="{{%20route('medicines.index')%20}}">Cancel</a>
Enter fullscreen mode Exit fullscreen mode

@endsection

medicines/show.blade.php
Create/open resources/views/medicines/show.blade.php:
blade@extends('layouts.app')

@section('content')

<h2>{{ $medicine-&gt;name }}</h2>


    <p><strong>Generic Name:</strong> {{ $medicine-&gt;generic_name }}</p>
    <p><strong>Category:</strong> {{ $medicine-&gt;category }}</p>
    <p><strong>Quantity:</strong> {{ $medicine-&gt;quantity }}</p>
    <p><strong>Expiration Date:</strong> {{ $medicine-&gt;expiration_date-&gt;format('F d, Y') }}</p>
    <p><strong>Price:</strong> ₱{{ number_format($medicine-&gt;price, 2) }}</p>
    <p>
        <strong>Status:</strong>
        @if($medicine-&gt;status === 'available')
            <span>Available</span>
        @elseif($medicine-&gt;status === 'low_stock')
            <span>Low Stock</span>
        @else
            <span>Out of Stock</span>
        @endif
    </p>
    <p><strong>Added:</strong> {{ $medicine-&gt;created_at-&gt;format('F d, Y') }}</p>


<a href="{{%20route('medicines.edit',%20$medicine)%20}}">Edit</a>
<a href="{{%20route('medicines.index')%20}}">Back</a>
Enter fullscreen mode Exit fullscreen mode

@endsection

reports/index.blade.php
Create/open resources/views/reports/index.blade.php:
blade@extends('layouts.app')

@section('content')

<h2>Medicine Reports</h2>



        Filter by Category

            -- All Categories --
            @foreach($categories as $cat)

                    {{ $cat }}

            @endforeach




        Filter by Expiration Status

            -- All --

                Not Expired


                Expired





        Filter
        <a href="{{%20route('reports.index')%20}}">Reset</a>




    <a href="{{%20route('reports.pdf',%20request()-&gt;query())%20}}">
        Export PDF
    </a>
    <a href="{{%20route('reports.csv',%20request()-&gt;query())%20}}">
        Export CSV
    </a>


<p>Showing <strong>{{ $medicines-&gt;count() }}</strong> result(s)</p>

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Generic Name</th>
            <th>Category</th>
            <th>Quantity</th>
            <th>Expiration Date</th>
            <th>Price</th>
            <th>Status</th>
        </tr>
    </thead>

    <tbody>
        @forelse($medicines as $medicine)
            <tr>
                <td>{{ $medicine-&gt;name }}</td>
                <td>{{ $medicine-&gt;generic_name }}</td>
                <td>{{ $medicine-&gt;category }}</td>
                <td>{{ $medicine-&gt;quantity }}</td>
                <td>
                    {{ $medicine-&gt;expiration_date-&gt;format('M d, Y') }}
                    @if($medicine-&gt;isExpired())
                        <span>Expired</span>
                    @endif
                </td>
                <td>₱{{ number_format($medicine-&gt;price, 2) }}</td>
                <td>
                    @if($medicine-&gt;status === 'available')
                        <span>Available</span>
                    @elseif($medicine-&gt;status === 'low_stock')
                        <span>Low Stock</span>
                    @else
                        <span>Out of Stock</span>
                    @endif
                </td>
            </tr>
        @empty
            <tr>
                <td colspan="7">No results found.</td>
            </tr>
        @endforelse
    </tbody>
</table>
Enter fullscreen mode Exit fullscreen mode

@endsection

Top comments (0)