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
- 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:
<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.