Laravel 9

create an invoice laravel and Ajax and database

Step 1: Create Database Tables You will need to create a database table for storing the product details, customer details, and invoice details. Here is an example of how you can create the tables:

  • products table:
    • id (primary key)
    • name
    • price
  • customers table:
    • id (primary key)
    • name
    • email
    • address
  • invoices table:
    • id (primary key)
    • customer_id (foreign key)
    • invoice_date
    • total_amount
    • amount_paid
    • discount
    • net_amount

Step 2: Create Models You will need to create models for each of the tables. You can use the following commands to create the models:

php artisan make:model Product php artisan make:model Customer php artisan make:model Invoice

Step 3: Create Controllers You will need to create controllers for handling the invoice creation process. Here is an example of how you can create a controller:

php artisan make:controller InvoiceController

In the InvoiceController, you will need to create the following functions:

  • create: This function will display a form for the user to enter the customer details and select the products they want to purchase.
  • store: This function will receive the form data submitted by the user and create a new invoice in the database.
  • show: This function will display the invoice details for a particular invoice.

Step 4: Create Views You will need to create views for the create and show functions in the InvoiceController. Here is an example of how you can create the views:

  • resources/views/invoice/create.blade.php: This view will display the form for the user to enter the customer details and select the products they want to purchase.
  • resources/views/invoice/show.blade.php: This view will display the invoice details for a particular invoice.

Step 5: Create Routes You will need to create routes for the InvoiceController. Here is an example of how you can create the routes:

Route::get(‘/invoice/create’, ‘InvoiceController@create’); Route::post(‘/invoice/store’, ‘InvoiceController@store’); Route::get(‘/invoice/{id}’, ‘InvoiceController@show’);

Step 6: Implement Ajax You can implement Ajax to update the invoice total, amount paid, discount and net amount in real-time as the user enters the product quantity. Here is an example of how you can implement Ajax:

  • Add the jQuery library to your project.
  • Write an Ajax function to handle the product quantity input event.
  • In the Ajax function, send a request to the server to calculate the invoice total, amount paid, discount and net amount based on the product quantity entered by the user.
  • Update the relevant fields in the invoice form with the calculated values returned by the server.

That’s it! With these steps, you should now have a basic invoicing system that can create and display invoices with real-time calculation using Laravel, Ajax and database.

 

Here is a basic code implementation for the invoicing system using Laravel, Ajax and database:

Step 1: Create Database Tables You can create the tables using Laravel’s migration feature. Run the following command in your terminal:

php artisan make:migration create_products_table –create=products php artisan make:migration create_customers_table –create=customers php artisan make:migration create_invoices_table –create=invoices

In the migration files, add the following code:

  • products table:
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->decimal('price', 8, 2);
    $table->timestamps();
});
  • customers table:
Schema::create('customers', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->string('address');
    $table->timestamps();
});
  • invoices table:
Schema::create('invoices', function (Blueprint $table) {
    $table->id();
    $table->foreignId('customer_id')->constrained();
    $table->date('invoice_date');
    $table->decimal('total_amount', 8, 2);
    $table->decimal('amount_paid', 8, 2);
    $table->decimal('discount', 8, 2)->default(0);
    $table->decimal('net_amount', 8, 2)->default(0);
    $table->timestamps();
});

Run the following command to migrate the database:

php artisan migrate

Step 2: Create Models Create the models using the following command:

php artisan make:model Product php artisan make:model Customer php artisan make:model Invoice

Add the following code to the models:

  • Product model:
class Product extends Model
{
    protected $fillable = ['name', 'price'];
}
  • Customer model:
class Customer extends Model
{
    protected $fillable = ['name', 'email', 'address'];
}
  • Invoice model:
class Invoice extends Model
{
    protected $fillable = ['customer_id', 'invoice_date', 'total_amount', 'amount_paid', 'discount', 'net_amount'];

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function invoiceItems()
    {
        return $this->hasMany(InvoiceItem::class);
    }
}

Step 3: Create Controllers Create the controller using the following command:

php artisan make:controller InvoiceController

Add the following code to the controller:

class InvoiceController extends Controller
{
    public function create()
    {
        $customers = Customer::all();
        $products = Product::all();
        return view('invoice.create', compact('customers', 'products'));
    }

    public function store(Request $request)
    {
        $invoice = new Invoice;
        $invoice->customer_id = $request->customer_id;
        $invoice->invoice_date = $request->invoice_date;
        $invoice->total_amount = $request->total_amount;
        $invoice->amount_paid = $request->amount_paid;
        $invoice->discount = $request->discount;
        $invoice->net_amount = $request->net_amount;
        $invoice->save();

        foreach ($request->product_id as $key => $value) {
            $invoiceItem = new InvoiceItem;
            $invoiceItem->invoice_id = $invoice->id;
            $invoiceItem->product_id = $value;
            $invoiceItem->quantity = $request->quantity[$key];
        $invoiceItem->price = $request->price[$key];
        $invoiceItem->total = $request->total[$key];
        $invoiceItem->save();
    }

    return redirect()->route('invoice.index')->with('success', 'Invoice created successfully.');
}
}

Step 4: Create Routes Add the following code to your web.php file:

Route::get('/invoice/create', [InvoiceController::class, 'create'])->name('invoice.create');
Route::post('/invoice/store', [InvoiceController::class, 'store'])->name('invoice.store');

Step 5: Create Views Create the following views in your resources/views folder:

  • invoice/create.blade.php:
<form id="invoiceForm" method="post" action="{{ route('invoice.store') }}">
    @csrf
    <div class="row">
        <div class="col-sm-6">
            <div class="form-group">
                <label for="customer_id">Customer</label>
                <select name="customer_id" class="form-control">
                    <option value="">Select Customer</option>
                    @foreach ($customers as $customer)
                    <option value="{{ $customer->id }}">{{ $customer->name }}</option>
                    @endforeach
                </select>
            </div>
        </div>
        <div class="col-sm-6">
            <div class="form-group">
                <label for="invoice_date">Invoice Date</label>
                <input type="date" name="invoice_date" class="form-control">
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-sm-12">
            <table class="table table-bordered" id="productTable">
                <thead>
                    <tr>
                        <th>Product</th>
                        <th>Quantity</th>
                        <th>Price</th>
                        <th>Total</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>
                            <select name="product_id[]" class="form-control product_id">
                                <option value="">Select Product</option>
                                @foreach ($products as $product)
                                <option value="{{ $product->id }}">{{ $product->name }}</option>
                                @endforeach
                            </select>
                        </td>
                        <td><input type="number" name="quantity[]" class="form-control quantity" min="1"></td>
                        <td><input type="number" name="price[]" class="form-control price" min="0"></td>
                        <td><input type="number" name="total[]" class="form-control total" min="0" readonly></td>
                        <td><button type="button" class="btn btn-danger btn-sm removeRow"><i class="fas fa-minus"></i></button></td>
                    </tr>
                </tbody>
                <tfoot>
                    <tr>
                        <td colspan="3"><button type="button" class="btn btn-primary btn-sm addRow"><i class="fas fa-plus"></i> Add Row</button></td>
                        <td>Total:</td>
                        <td><input type="number" name="total_amount" id="total_amount" class="form-control" min="0" readonly></td>
                    </tr>
                    <tr>
                        <td colspan="3"></td>
                        <td>Discount:</td>
                        <td><input type="number" name="discount" id="discount" class="form-control" min="0"></td>
                    </tr>
          <tr>
                    <td colspan="3"></td>
                    <td>Amount Paid:</td>
                    <td><input type="number" name="amount_paid" id="amount_paid" class="form-control" min="0"></td>
                </tr>
                <tr>
                    <td colspan="3"></td>
                    <td>Net Total:</td>
                    <td><input type="number" name="net_total" id="net_total" class="form-control" min="0" readonly></td>
                </tr>
            </tfoot>
        </table>
    </div>
</div>

<div class="row">
    <div class="col-sm-12">
        <button type="submit" class="btn btn-success"><i class="fas fa-save"></i> Save</button>
    </div>
</div>
</form>
<script>
    $(document).ready(function() {
        // Add new row
        $('.addRow').on('click', function() {
            addRow();
        });

        // Remove row
        $(document).on('click', '.removeRow', function() {
            $(this).closest('tr').remove();
            calculateTotal();
        });

        // Calculate total
        $(document).on('keyup', '.quantity, .price', function() {
            var tr = $(this).closest('tr');
            var quantity = tr.find('.quantity').val();
            var price = tr.find('.price').val();
            var total = (quantity * price).toFixed(2);
            tr.find('.total').val(total);
            calculateTotal();
        });

        // Calculate net total
        $(document).on('keyup', '#discount, #amount_paid', function() {
            calculateTotal();
        });

        // Add new row function
        function addRow() {
            var html = '';
            html += '<tr>';
            html += '<td><select name="product_id[]" class="form-control product_id"><option value="">Select Product</option>@foreach ($products as $product)<option value="{{ $product->id }}">{{ $product->name }}</option>@endforeach</select></td>';
            html += '<td><input type="number" name="quantity[]" class="form-control quantity" min="1"></td>';
            html += '<td><input type="number" name="price[]" class="form-control price" min="0"></td>';
            html += '<td><input type="number" name="total[]" class="form-control total" min="0" readonly></td>';
            html += '<td><button type="button" class="btn btn-danger btn-sm removeRow"><i class="fas fa-minus"></i></button></td>';
            html += '</tr>';
            $('#productTable tbody').append(html);
        }

        // Calculate total function
        function calculateTotal() {
            var total = 0;
            $('.total').each(function() {
                total += parseFloat($(this).val());
            });
            $('#total_amount').val(total.toFixed(2));

            var discount = $('#discount').val();
            if (discount > 0) {
                var netTotal = (total - discount).toFixed(2);
            } else {
                var netTotal = total.toFixed(2);
            }
            $('#net_total').val(netTotal);

            var amountPaid = $('#amount_paid').val();
            if (amountPaid > 0) {
                var balanceDue = (netTotal - amountPaid).toFixed(2);
            } else {
                var balanceDue = netTotal;
            }
            $('#balance_due').val(balanceDue);
        }
    });
</script>
This is the form for creating a new invoice. It has

fields for selecting a product, entering the quantity and price, and adding a new row for another product. It also has fields for entering the discount, amount paid, and calculating the total amount and net total.

The form is built using HTML and Bootstrap classes for styling. It uses jQuery for handling events such as adding a new row, removing a row, and calculating the total amount and net total.

In the script section, you can see the code for handling these events. The addRow() function is called when the user clicks on the “Add New Row” button. It appends a new row to the table with input fields for the product, quantity, price, and total amount.

The calculateTotal() function is called whenever the user changes the values of the quantity, price, discount, or amount paid fields. It calculates the total amount, net total, and balance due based on the values entered by the user.

The $(document).ready() function is used to ensure that the DOM is fully loaded before executing any jQuery code.

Overall, this form and script provide a simple and user-friendly way to create an invoice with multiple products and calculate the total and net amount.

To complete the process of creating an invoice with Laravel and Ajax, we also need to handle the submission of the form and storing the data in the database. Here’s an example of how we can do that:

First, we need to create a new route in our web.php file to handle the form submission:

Route::post('/invoices', 'InvoiceController@store')->name('invoices.store');

This route will call the store() method of the InvoiceController when the form is submitted.

Next, we need to create the InvoiceController and implement the store() method. Here’s an example:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Invoice;
use App\Models\InvoiceItem;

class InvoiceController extends Controller
{
    public function store(Request $request)
    {
        // Validate the request data
        $request->validate([
            'customer_name' => 'required|max:255',
            'customer_email' => 'required|email|max:255',
            'product_id.*' => 'required|exists:products,id',
            'quantity.*' => 'required|numeric|min:1',
            'price.*' => 'required|numeric|min:0',
            'discount' => 'nullable|numeric|min:0',
            'amount_paid' => 'nullable|numeric|min:0',
        ]);

        // Create a new invoice
        $invoice = new Invoice();
        $invoice->customer_name = $request->input('customer_name');
        $invoice->customer_email = $request->input('customer_email');
        $invoice->total_amount = $request->input('total_amount');
        $invoice->discount = $request->input('discount');
        $invoice->net_total = $request->input('net_total');
        $invoice->amount_paid = $request->input('amount_paid');
        $invoice->balance_due = $request->input('balance_due');
        $invoice->save();

        // Create invoice items
        $productIds = $request->input('product_id');
        $quantities = $request->input('quantity');
        $prices = $request->input('price');
        $totals = $request->input('total');

        foreach ($productIds as $key => $productId) {
            $item = new InvoiceItem();
            $item->invoice_id = $invoice->id;
            $item->product_id = $productId;
            $item->quantity = $quantities[$key];
            $item->price = $prices[$key];
            $item->total = $totals[$key];
            $item->save();
        }

        return response()->json(['success' => true]);
    }
}

In this method, we first validate the input data to ensure that it is correct and complete. Then, we create a new Invoice object and populate its fields with the input data. We save the invoice to the database.

Next, we loop through the invoice items and create a new InvoiceItem object for each item. We set the invoice_id, product_id, quantity, price, and total fields of each item, and then save it to the database.

Finally, we return a JSON response indicating that the invoice was successfully created.

Now that we have the store() method, we need to modify the form to use Ajax to submit the data asynchronously. Here’s an example:

javascript
<script>
    $(document).ready(function() {
        // Add new row
        $('.addRow').on('click', function() {
            addRow();
        });

        // Remove row
        $(document).on('click', '.removeRow', function() {
            $(this.closest('tr').remove();
calculateTotal();
});
   // Calculate totals
    $(document).on('input', '.quantity, .price, #discount, #amount_paid', function() {
        calculateTotal();
    });

    // Submit form
    $('#invoiceForm').on('submit', function(e) {
        e.preventDefault();

        $.ajax({
            type: 'POST',
            url: '{{ route("invoices.store") }}',
            data: $('#invoiceForm').serialize(),
            success: function(response) {
                if (response.success) {
                    $('#successMessage').removeClass('d-none');
                    $('#invoiceForm')[0].reset();
                    $('#invoiceTable tbody tr').remove();
                    calculateTotal();
                } else {
                    alert('Error creating invoice. Please try again later.');
                }
            },
            error: function() {
                alert('Error creating invoice. Please try again later.');
            }
        });
    });

    // Functions
    function addRow() {
        var row = '<tr>' +
            '<td><select name="product_id[]" class="form-control product_id" required>' +
            '<option value="">Select Product</option>' +
            '@foreach($products as $product)' +
            '<option value="{{ $product->id }}" data-price="{{ $product->price }}">{{ $product->name }}</option>' +
            '@endforeach' +
            '</select></td>' +
            '<td><input type="number" name="quantity[]" class="form-control quantity" required min="1"></td>' +
            '<td><input type="number" name="price[]" class="form-control price" required min="0" readonly></td>' +
            '<td><input type="number" name="total[]" class="form-control total" required min="0" readonly></td>' +
            '<td><button type="button" class="btn btn-danger removeRow"><i class="fas fa-trash"></i></button></td>' +
            '</tr>';

        $('#invoiceTable tbody').append(row);
    }

    function calculateTotal() {
        var total = 0;

        $('.total').each(function() {
            total += parseInt($(this).val());
        });

        var discount = parseInt($('#discount').val()) || 0;
        var amountPaid = parseInt($('#amount_paid').val()) || 0;
        var netTotal = total - discount;
        var balanceDue = netTotal - amountPaid;

        $('#total_amount').val(total);
        $('#net_total').val(netTotal);
        $('#balance_due').val(balanceDue);
    }
});
</script>

In this script, we add a new event handler for the form submission. When the user submits the form, we prevent the default form submission and use Ajax to submit the data to the invoices.store route. We serialize the form data using the serialize() method and send it as the request payload.

If the request is successful, we display a success message and clear the form and table. If the request fails, we display an error message.

With these changes, our invoice form is now fully functional and can create new invoices and store them in the database.

Next, we need to create the store method in our InvoiceController to handle the form submission and store the invoice in the database.

public function store(Request $request)
{
    $validator = Validator::make($request->all(), [
        'customer_name' => 'required|max:255',
        'customer_email' => 'required|email|max:255',
        'product_id.*' => 'required|exists:products,id',
        'quantity.*' => 'required|integer|min:1',
        'price.*' => 'required|integer|min:0',
        'total.*' => 'required|integer|min:0',
        'discount' => 'integer|min:0',
        'amount_paid' => 'integer|min:0',
        'total_amount' => 'required|integer|min:0',
        'net_total' => 'required|integer|min:0',
        'balance_due' => 'required|integer',
    ]);

    if ($validator->fails()) {
        return response()->json(['success' => false]);
    }

    $invoice = new Invoice;
    $invoice->customer_name = $request->input('customer_name');
    $invoice->customer_email = $request->input('customer_email');
    $invoice->discount = $request->input('discount');
    $invoice->amount_paid = $request->input('amount_paid');
    $invoice->total_amount = $request->input('total_amount');
    $invoice->net_total = $request->input('net_total');
    $invoice->balance_due = $request->input('balance_due');
    $invoice->save();

    $products = $request->input('product_id');
    $quantities = $request->input('quantity');
    $prices = $request->input('price');
    $totals = $request->input('total');

    for ($i = 0; $i < count($products); $i++) {
        $invoiceItem = new InvoiceItem;
        $invoiceItem->product_id = $products[$i];
        $invoiceItem->quantity = $quantities[$i];
        $invoiceItem->price = $prices[$i];
        $invoiceItem->total = $totals[$i];
        $invoiceItem->invoice_id = $invoice->id;
        $invoiceItem->save();
    }

    return response()->json(['success' => true]);
}

In this method, we first validate the form data using the Validator facade. If the validation fails, we return a JSON response with success set to false.

If the validation passes, we create a new Invoice instance and set its properties to the corresponding form values. We then save the invoice to the database.

Next, we loop through each item in the invoice and create a new InvoiceItem instance for each item. We set its properties to the corresponding form values and set its invoice_id property to the ID of the newly created invoice. We then save the invoice item to the database.

Finally, we return a JSON response with success set to true.

With these changes, our Laravel and Ajax invoice creation form is now complete and fully functional.

dylanu

A programmer who cares about programming matters for the web application, mobile application, and servers and their protection

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button