Step 01: In OrderItemController, adding edit() method
public function edit( OrderItem $order_item ) { $order_item->load(['order','product','fwidth','profile']); $meta_title = 'Edit Order ' . $order_item->order->name; $products = Product::orderBy( 'sequence', 'asc' )->get(); $profiles = Profile::orderBy( 'sequence', 'asc' )->get(); $fwidths = FrameWidth::orderBy( 'sequence', 'asc' )->get(); return view( 'order_items.edit', compact( 'meta_title', 'order_item', 'products', 'profiles', 'fwidths' ) ); }
Step 02: Adding edit.blade.php under resources/view/order_items folder inside section blade directive extending app layout
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <h2 class="float-start">Edit Order Item</h2> <div class="float-end"> <a class="btn btn-sm btn-primary" href="{{ route('order_items.index').'?order_id='.$order_item->order_id }}"> Back to order items</a> </div> <div class="clearfix"></div> <div class="card "> <div class="card-body"> <form method="post" action="{{ route('order_items.update', $order_item->id) }}" id="orderCrfrm" method="post"> @csrf @method('PUT') <input type="hidden" name="url_process_cost" value="{{ url('').'/order_items/cal_cost' }}" /> <div class="form-group mb-2"> <label for="title">Choose Product <span class="text-danger">*</span></label> <br> <select name="product" class="form-control product-select2 "> <option value="">--</option> @foreach ($products as $product) @php $selected = $product->id == $order_item->product_id ? 'selected' : ''; @endphp <option value="{{ $product->id }}" {{ $selected }}>{{ $product->name }} - ${{ number_format($product->cost, 2) }} / sf</option> @endforeach </select> @if ($errors->has('product')) <span class="text-danger">{{ $errors->first('product') }}</span> @endif </div> <div class="form-group mb-2"> <label for="title">Choose Profile <span class="text-danger">*</span></label> <br> <select name="profile_id" class="form-control"> <option value="">--</option> @foreach ($profiles as $profiler) @php $selected = $profiler->id == $order_item->profile_id ? 'selected' : ''; @endphp <option value="{{ $profiler->id }}" {{ $selected }}>{{ $profiler->name }} </option> @endforeach </select> @if ($errors->has('profile_id')) <span class="text-danger">{{ $errors->first('profile_id') }}</span> @endif </div> <div class="form-group mb-2"> <label for="title">Frame Width <span class="text-danger">*</span></label> <br> <select name="frame_width" class="form-control"> <option value="">--</option> @foreach ($fwidths as $frame_width) @php $selected = $frame_width->id == $order_item->frame_width_id ? 'selected' : ''; @endphp <option value="{{ $frame_width->id }}" {{ $selected }}> {{ $frame_width->name }} - {{ $frame_width->percentage }}% </option> @endforeach </select> @if ($errors->has('frame_width')) <span class="text-danger">{{ $errors->first('frame_width') }}</span> @endif </div> <div class="form-group mb-2"> <label for="title">Width ( In Inches ) <span class="text-danger">*</span></label> <br> <input name="width" class="form-control" placeholder="width" title="width" type="text" id="width" value="{{ $order_item->width }}" /> @if ($errors->has('width')) <span class="text-danger">{{ $errors->first('width') }}</span> @endif </div> <div class="form-group mb-2"> <label for="title">Height ( In Inches ) <span class="text-danger">*</span></label> <br> <input name="height" class="form-control" placeholder="height" title="height" type="text" id="height" value="{{ $order_item->height }}" /> @if ($errors->has('height')) <span class="text-danger">{{ $errors->first('height') }}</span> @endif </div> <div class="form-group mb-2"> <label for="title">Total Square Feet </label> <br> <input name="total_square_feet" class="form-control" style="background-color:darkgray;" placeholder="total square feet" title="total square feet" type="text" readonly value="{{ $order_item->total_square_feet }}" /> </div> <div class="form-group mb-2"> <label for="title">Quantity <span class="text-danger">*</span></label> <br> <input name="quantity" class="form-control" placeholder="quantity" title="quantity" type="text" id="quantity" value="{{ $order_item->quantity }}" /> @if ($errors->has('quantity')) <span class="text-danger">{{ $errors->first('quantity') }}</span> @endif </div> <div class="form-group mb-2"> <label for="title">Cost </label> <br> <input name="order_item_cost" class="form-control" style="background-color:darkgray;" placeholder="cost" title="cost" type="text" readonly value="{{ $order_item->cost }}" /> </div> <div class="form-group mb-2"> <label for="title">Additional Request</label> <br> <textarea class="form-control" rows="3" name="additional_request" placeholder="Additional Request">{{ $order_item->additional_request }}</textarea> </div> <input class="btn btn-sm btn-primary" class="form-control" type="submit" name="action" value="Edit Item"> </form> </div> </div> </div> </div> </div> @endsection
Step 03: Back in OrderItemController adding update() method like below and keeping to edit page after editing with flash message at the top
public function update( OrderItem $order_item, Request $request ) { $request->validate( [ 'product' => 'required', 'profile_id' => 'required', 'frame_width' => 'required', 'width' => 'required', 'height' => 'required', 'quantity' => 'required'] ); $order_item->update([ 'order_id' => $order_item->order_id, 'product_id' => $request->post( 'product' ), 'profile_id' => $request->post( 'profile_id' ), 'frame_width_id' => $request->post( 'frame_width' ), 'width' => $request->post( 'width' ), 'height' => $request->post( 'height' ), 'total_square_feet' => $order_item->calculateTotSqFeet( $request->post( 'width' ), $request->post( 'height' ) ), 'quantity' => $request->post( 'quantity' ), 'cost' => $request->post( 'order_item_cost' ), 'additional_request' => $request->post( 'additional_request' ) ?? '', ]); return redirect()->route( 'order_items.edit', $order_item->id )->with( 'success', 'Item edited successfully.' ); }
Step 04: Deleting order item data
public function destroy( OrderItem $order_item ) { $orderId = $order_item->order_id; $order_item->delete(); return redirect()->route( 'order_items.index', 'order_id='.$orderId )->with( 'success', 'Order item deleted successfully' ); }
A few optimized code implementations
Step 05: Changing input value name 'order_item_cost' from 'product_cost' as we have changed this value above in edit.blade.php view blade file. Now we need to replicate this change in all the relevant files. This is changed because calculation of the values are being saved to cost field of order items table which is later being used in preview.blade.php for showing up those calculation.
// inside process.js under resources/js/orders folder $('input[name=order_item_cost]').val(data); // resources/views/orders/create.blade.php folder, resources/views/order_items/create.blade.php folder <div class="form-group mb-2"> <label for="title">Cost </label> <br> <input name="order_item_cost" class="form-control" style="background-color:darkgray;" placeholder="cost" title="cost" type="text" readonly /> </div> // resources/views/order_items/preview.blade.php // from this $priceParams = ['quantity' => $orderItem->quantity, 'cost' => $orderItem->cost, 'percentage' => $orderItem->fwidth->percentage, 'total_square_feet' => $orderItem->total_square_feet ]; $cost = $orderItem->calculateOrderPrice($priceParams); $totalCost = $totalCost + $cost; $totalsqf = $totalsqf + $orderItem->total_square_feet; // to this $cost = $orderItem->cost; $totalCost = $totalCost + $cost; $totalsqf = $totalsqf + $orderItem->total_square_feet; // OrderItemController.php // inside store() method // from this $item->create([ 'order_id' => $orderId, 'product_id' => $request->post( 'product' ), 'profile_id' => $request->post( 'profile_id' ), 'frame_width_id' => $request->post( 'frame_width' ), 'width' => $request->post( 'width' ), 'height' => $request->post( 'height' ), 'total_square_feet' => $item->calculateTotSqFeet( $request->post( 'width' ), $request->post( 'height' ) ), 'quantity' => $request->post( 'quantity' ), 'cost' => Product::where('id',$request->post( 'product' ))->first()->cost, // optimized 'additional_request' => $request->post( 'additional_request' ) ?? '', ]); // to this $item = new OrderItem(); $item->create([ 'order_id' => $orderId, 'product_id' => $request->post( 'product' ), 'profile_id' => $request->post( 'profile_id' ), 'frame_width_id' => $request->post( 'frame_width' ), 'width' => $request->post( 'width' ), 'height' => $request->post( 'height' ), 'total_square_feet' => $item->calculateTotSqFeet( $request->post( 'width' ), $request->post( 'height' ) ), 'quantity' => $request->post( 'quantity' ), 'cost' => $request->post( 'order_item_cost' ), // optimized 'additional_request' => $request->post( 'additional_request' ) ?? '', ]); // OrderController.php // inside store() method // from this $item = new OrderItem(); $item->create([ 'order_id' => $order->id, 'product_id' => $request->post( 'product' ), 'profile_id' => $request->post( 'profile_id' ), 'frame_width_id' => $request->post( 'frame_width' ), 'width' => $request->post( 'width' ), 'height' => $request->post( 'height' ), 'total_square_feet' => $item->calculateTotSqFeet( $request->post( 'width' ), $request->post( 'height' ) ), 'quantity' => $request->post( 'quantity' ), 'cost' => Product::where('id',$request->post( 'product' ))->first()->cost, 'additional_request' => $request->post( 'additional_request' ), ]); // to this $item = new OrderItem(); $item->create([ 'order_id' => $order->id, 'product_id' => $request->post( 'product' ), 'profile_id' => $request->post( 'profile_id' ), 'frame_width_id' => $request->post( 'frame_width' ), 'width' => $request->post( 'width' ), 'height' => $request->post( 'height' ), 'total_square_feet' => $item->calculateTotSqFeet( $request->post( 'width' ), $request->post( 'height' ) ), 'quantity' => $request->post( 'quantity' ), 'cost' => $request->post( 'order_item_cost' ), 'additional_request' => $request->post( 'additional_request' ), ]);
Step 06: Preventing order item preview page when there are no items for an order
// OrderItemController.php //inside index() method public function index( Request $request ) { $orderId = $request->post( 'order_id' ); $order_items = OrderItem::with(['order','product','fwidth','profile'])->where( 'order_id', $orderId)->get(); //dd($order_items); if( $order_items->count() > 0 ) { $meta_title = 'Preview Order for company "' . $order_items[0]->order->company_name. '" and job/po "'. $order_items[0]->order->job_number. '"'; //dd($meta_title); } else { return redirect()->route( 'orders.edit', $orderId )->with('error', 'No Item is available under this order'); } return view( 'order_items.preview', compact( 'meta_title', 'order_items' ) ); } // OrderController.php // inside resources/views/orders/edit.blade.php // Adding clickable link for order item for creating item under an order just beside edit button in order edit page <input class="btn btn-sm btn-primary" class="form-control" type="submit" name="action" value="Edit"> <a class="btn btn-sm btn-info" href="{{ route('order_items.create', 'order_id='.$order->id) }}">Add Item to Order</a>