I have here a datatable with a form inside that has 3 submit buttons. I did a switch statement which it checks what submit button was clicked, then performs the operation of that submit button on my store()
function. Currently, I'm trying to submit the form using ajax. If I remove the switch
statement, and just return one operation/function.e.g. saveCredit()
, then it saves data in the database. However, with switch
statement, in place, it doesn't save any data.
Also, another instance is if I remove the e.preventDefault()
, it saves data in the database but it redirects to make-a-sale/save-purchase
route which should not be. It must redirect to the same page. How can I make the submit buttons save the data in the database even with switch
statement and e.preventDefault()
in place? How can make it redirect to the current page? What am I doing wrong here?
Please see my controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\{
Customer\BillingInfo,
Customer,
Product,
Purchases,
SetupBusiness
};
use App\Traits\PrintReceiptTrait;
use Carbon\Carbon;
use Picqer;
use Auth;
class PurchasesController extends Controller
{
use PrintReceiptTrait;
public function index()
{
return view('make-a-sale.index', ['has_id' => false]);
}
public function indexWithId($product_id)
{
return view('make-a-sale.index', ['product_id' => $product_id, 'has_id' => true]);
}
public function create()
{
return view('make-a-sale.index');
}
public function computeAndConvertData(Request $request)
{
$qty_per_item = array_map('intval', $request->qty);
$zero = floatval('0.00');
$payment = floatval($request->payment);
$total = floatval($request->total);
$balance = $total - $payment;
$new_data = array(
'qty_per_item' => $qty_per_item,
'zero' => $zero,
'payment' => $payment,
'total' => $total,
'balance' => $balance
);
return $new_data;
}
public function saveCredit(Request $request)
{
$product_ids = array_map('intval', $request->product_id);
$cod = $this->computeAndConvertData($request);
$data = $this->createData($request, $product_ids, $cod['qty_per_item'], $cod['balance']);
$this->createPurchaseData($data, $product_ids, $cod['qty_per_item'], $cod['zero'], $cod['total']);
$this->updateProductQtyOnHand($product_ids, $cod['qty_per_item']);
return redirect()->route('make-a-sale.index');
}
public function savePurchaseAndPrint(Request $request)
{
$product_ids = array_map('intval', $request->product_id);
$cod = $this->computeAndConvertData($request);
$payment = $cod['payment'] == $cod['zero'] ? $cod['zero'] : $request->payment;
$balance = $cod['balance'] != $cod['zero'] ? $request->total : $cod['balance'];
$data = $this->createData($request, $product_ids, $cod['qty_per_item'], $balance);
$purchase = $this->createPurchaseData($data, $product_ids, $cod['qty_per_item'], $payment, $balance);
$this->updateProductQtyOnHand($product_ids, $cod['qty_per_item']);
return $this->printReceipt($purchase->code, $purchase->barcode, $purchase->product_id, $purchase->qty_per_item, $purchase->balance);
}
public function savePurchase(Request $request)
{
$product_ids = array_map('intval', $request->product_id);
$cod = $this->computeAndConvertData($request);
$data = $this->createData($request, $product_ids, $cod['qty_per_item'], $cod['balance']);
$this->createPurchaseData($data, $product_ids, $cod['qty_per_item'], $request->payment, $cod['balance']);
$this->updateProductQtyOnHand($product_ids, $cod['qty_per_item']);
return redirect()->route('make-a-sale.index');
}
public function store(Request $request)
{
switch($request->get('action_create')) {
case 'credit':
$this->saveCredit($request);
break;
case 'save_and_print':
$this->savePurchaseAndPrint($request);
break;
case 'save':
$this->savePurchase($request);
break;
default:
return redirect()->route('make-a-sale.index');
}
}
private function generateRandomNumbers($length = 12)
{
$num = '0123456789';
$num_length = strlen((string)$num);
$random_number = '';
for ($i = 0; $i < $length; $i ) {
$random_number .= $num[rand(0, $num_length - 1)];
}
return $random_number;
}
private function generateBarcode($code_to_convert)
{
$generator = new Picqer\Barcode\BarcodeGeneratorHTML();
$barcode = $generator->getBarcode($code_to_convert, $generator::TYPE_CODE_128, 2, 35);
return $barcode;
}
public function createData(Request $request, $product_ids, $qty_per_item, $balance)
{
$code = $this->generateRandomNumbers();
$validation = $request->validate([
'code' => 'unique:purchases',
'product_id' => 'required',
'customer_id' => 'required'
]);
$data = array_merge($validation, [
'code' => $code,
'barcode' => $this->generateBarcode($code),
'status' => 'Regular',
'type' => $balance == floatval('0.00') ? 'Sale' : 'Accounts Receivables',
'cashier_id' => Auth::user()->id,
'customer_id' => $request->customer_id,
'product_id' => $product_ids,
'no_of_items' => $request->no_of_items,
'qty_per_item' => $qty_per_item,
'payment_type' => $balance <= 0 ? 'cash' : 'credit',
'total' => $request->total,
'created_at' => Carbon::now()->timestamp
]);
return $data;
}
public function createPurchaseData($data, $product_id, $qty_sold, $payment, $balance)
{
$purchases = Purchases::create(array_merge($data, [
'payment' => $payment,
'balance' => $balance,
'product_details' => $this->createProductsDetails($product_id, $qty_sold)
]));
return $purchases;
}
public function updateProductQtyOnHand($product_ids, $qty_per_item)
{
$products = array_combine($product_ids, $qty_per_item);
foreach ($products as $product_id => $receive_item_qty) {
$qty_on_hand = Product::where('id', '=', $product_id)->value('qty_on_hand');
$difference = $qty_on_hand - $receive_item_qty;
Product::select('qty_on_hand')->where('id', '=', $product_id)->update(['qty_on_hand' => $difference]);
}
}
}
Here's my route:
Route::post('make-a-sale/save-purchase', [PurchasesController::class, 'store'])->name('make-a-sale.store');
Here's some of my Ajax:
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$(document).ready(function() {
$.noConflict();
var tableId = '#tbl-make-a-sale';
// Footer button group actions
saveCredit(tableId);
savePurchase(tableId);
});
function saveCredit(tableId) {
$('#btn-credit').on('click', function(e) {
e.preventDefault();
if (!$("input[name='product_id[]']").val()) {
toastr.error('The table is empty. Please add some products first.');
} else {
let productIds = $("input[name='product_id[]']").map(function(){ return $(this).val(); }).get();
let qtyPerItem = $("input[name='qty[]']").map(function(){ return $(this).val(); }).get();
let params = {
product_id: productIds,
qty: qtyPerItem,
no_of_items: $("input[name='no_of_items']").val(),
customer_id: $("input[name='customer_id']").val(),
payment: parseFloat($('input[name="payment"]').val()),
total: parseFloat($('input[name="total"]').val()),
_token: $('meta[name="csrf-token"]').attr('content')
}
$.ajax({
url: 'make-a-sale/save-purchase',
type: 'POST',
data: params,
success: function(data) {
toastr.success("A new ledger has been created!");
$(tableId).DataTable().clear().draw(false);
$('#search-customers').val('0').trigger('change.select2').prop('disabled', true);
$('#cash-container, #txt-amount-due').hide();
},
error: function(xhr, status, error) {
let errors = xhr.responseJSON.errors;
for (var key in errors) {
if (errors.hasOwnProperty(key)) {
toastr.error(errors[key]);
}
}
}
});
}
});
}
function savePurchase(tableId) {
$('#btn-save').on('click', function(e) {
e.preventDefault();
if (!$("input[name='product_id[]']").val()) {
toastr.error('The table is empty. Please add some products first.');
} else {
let productIds = $("input[name='product_id[]']").map(function(){ return $(this).val(); }).get();
let qtyPerItem = $("input[name='qty[]']").map(function(){ return $(this).val(); }).get();
let params = {
product_id: productIds,
qty: qtyPerItem,
no_of_items: $("input[name='no_of_items']").val(),
customer_id: $("input[name='customer_id']").val(),
payment: parseFloat($('input[name="payment"]').val()),
total: parseFloat($('input[name="total"]').val()),
_token: $('meta[name="csrf-token"]').attr('content')
}
$.ajax({
url: 'make-a-sale/save-purchase',
type: 'POST',
data: params,
success: function(data) {
toastr.success("Products have been sold successfully!");
$(tableId).DataTable().clear().draw(false);
$('#search-customers').val('0').trigger('change.select2').prop('disabled', true);
$('#cash-container, #txt-amount-due').hide();
},
error: function(xhr, status, error) {
let errors = xhr.responseJSON.errors;
for (var key in errors) {
if (errors.hasOwnProperty(key)) {
toastr.error(errors[key]);
}
}
}
});
}
});
}
Here's my HTML:
<form id="form-make-a-sale" action="{{ route('make-a-sale.store') }}" method="post" enctype="multipart/form-data">
@csrf
<table id="tbl-make-a-sale" class="w-full tbl-responsive overflow-x-auto rounded-lg border-none tbl-default">
<thead class="w-min">
<tr>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">Actions</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">
Barcode
</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">
Name
</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">
Description
</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">
Qty. On Hand
</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">
Qty. To Sell
</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none hidden">
SRP
</th>
<th
class="px-6 py-0 bg-persian-blue h-16 text-left text-xs text-white uppercase tracking-wider border-none">
Ext. Price
</th>
</tr>
</thead>
<tbody class="bg-white"></tbody>
</table>
<div class="w-full pb-6 md:pb-0 border-t border-gray-200 md:border-none">
<div class="flex bg-white justify-between items-center">
<div class="pt-6 pb-0 px-6 whitespace-no-wrap">
<p class="text-2xl text-gray-700 font-bold">Total</p>
</div>
<div class="pt-6 pb-0 px-6 whitespace-no-wrap">
<p class="text-4xl text-gray-700 font-extrabold font-mono text-right">
<span id="total">₱ 0.00</span>
<input type="hidden" name="total" readonly/>
</p>
</div>
</div>
<div id="cash-container" style="display: none;">
<div class="flex justify-between items-center">
<div class="px-6 whitespace-no-wrap">
<p class="text-lg text-gray-700 font-bold">Cash</p>
</div>
<div class="px-6 whitespace-no-wrap">
<p class="text-lg text-gray-700 font-extrabold font-mono text-right">
<span id="cash">0.00</span>
</p>
</div>
</div>
</div>
</div>
<div class="mt-4 w-full md:border-t md:border-b md:border-gray-200">
<div id="amount-due-container" class="flex bg-persian-blue md:bg-white justify-between items-center">
<div class="p-6 whitespace-no-wrap">
<p id="lbl-amount-due" class="text-2xl text-gray-50 md:text-gray-700 font-bold">Amount Due</p>
</div>
<div class="p-6 whitespace-no-wrap">
<p id="txt-amount-due" class="text-3xl text-gray-50 md:text-gray-700 font-extrabold font-mono text-right">
<span id="amount_due"></span>
</p>
</div>
</div>
</div>
<div id="btn-footer-group-mas" class="m-6 justify-between">
<button type="button" class="px-8 py-4 text-md font-medium text-gray-50 transition-colors duration-300 transform bg-red-400 hover:bg-red-500 rounded hover:text-white focus:outline-none focus:ring cstm-size-m-mas cstm-size-w-full-mas btn-clear" name="clear" value="clear" tabindex="2">Clear
</button>
<div id="btn-footer-right-group-mas">
<button type="button" id="btn-cash" class="px-8 py-4 text-md font-medium text-white transition-colors duration-300 transform rounded bg-green-400 hover:bg-green-300 focus:outline-none focus:ring cstm-size-m-mas cstm-size-w-full-mas" data-hystmodal="#pay-in-cash-modal" tabindex="3">Cash
</button>
<button type="submit" id="btn-credit" class="px-8 py-4 text-md font-medium text-white transition-colors duration-300 transform rounded bg-yellow-400 hover:bg-yellow-300 focus:outline-none focus:ring cstm-size-m-mas cstm-size-w-full-mas credited" name="action_create" value="credit" tabindex="4">Credit
</button>
<button type="submit" id="btn-save-and-print" class="px-8 py-4 text-md font-medium text-indigo-400 transition-colors duration-300 transform border-2 border-indigo-400 rounded bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring disabled:opacity-40 cursor-not-allowed cstm-size-m-mas cstm-size-w-full-mas" name="action_create" value="save_and_print_receipt" tabindex="5">Save and Print Receipt
</button>
<button type="submit" id="btn-save" class="px-8 py-4 text-md font-medium text-white transition-colors duration-300 transform rounded bg-indigo-600 rounded hover:bg-indigo-500 focus:outline-none focus:ring cstm-last-el-size-m-mas cstm-size-w-full-mas" name="action_create" value="save" tabindex="6">Save
</button>
</div>
</div>
</form>
Any help is much appreciated.
CodePudding user response:
On the controller side instead of redirecting to the route, you can redirect JSON to the Ajax at frontend. For Example: Instead of:
return redirect()->route('make-a-sale.index');
You can:
return response()->json(["status"->true]);
CodePudding user response:
your question I doesn't understand but first check on submit Your Ajax send request to your controller function of not...
2nd thing, you don't need to write hardcoded url in ajax request...
$.ajax({
type: "GET",
url: "{{ route('home') }}?page=" page,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
// data: { id: deal_id, }
}).done(function( data ) {
//on success do your operation
})
.fail(function(jqXHR, ajaxOptions, thrownError)
alert('No response from server');
});
If you want to pass Param in URL like domainname.com/user/edit/{id} then you can pass to ajax as above same URL using route you...
simply do as like below
user_id = 3; //on click get user_id
url = "{{ route('admin.users.edit',':id') }}";
url = url.replace(':id', user_id);
then that url variable pass to ajax
$.ajax({
type: "POST",
url: url,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
// data: { id: deal_id, }
}).done(function( data ) {
//on success do your operation
})
.fail(function(jqXHR, ajaxOptions, thrownError)
alert('No response from server');
});
CodePudding user response:
Sorry @Harsh Patel if I cannot explain my question well.
I managed to solved it by:
return response()->json([$data]);
And adding redirect per case in my switch statement:
return redirect()->route('make-a-sale.index');
Switch statement:
public function store(Request $request)
{
switch($request->get('action_create')) {
case 'credit':
$this->saveCredit($request);
return redirect()->route('make-a-sale.index');
break;
case 'save_and_print':
$this->savePurchaseAndPrint($request);
break;
case 'save':
$this->savePurchase($request);
return redirect()->route('make-a-sale.index');
break;
default:
return redirect()->route('make-a-sale.index');
}
}
Thank you @Shree Sthapit