Store data in foreach loop in laravel 5.8 - php

I need your help with my situation in storing data.
I got a cart with several products, and now I want to store all these products in Order table at the same time by clicking submit button
My view blade.php
This view shows all products in the cart and I need to store these information in Ordertable
<form action="{{route('order.store')}}" method="post">
#csrf
#foreach ($cart as $ct)
<input type="text" name="product_id" value="{{$ct->id}}" hidden>
<input type="text" value="{{$ct->color}}" name="color" >
<input type="text" value="{{$ct->size}}" name="size" >
<input type="text" value="{{$ct->price}}" name="price" >
#endforeach
<button type="submit">submit</button>
</form>
In my Order table, I got these 4 columns need to fill in: product_id, color, size and price.
My foreach loop gets data from Cart table and all data were shown without errors.
My question is that How I can store these data to my Order table just by click on submit button once? What I should write in my store function in OrderController?
If my cart has 3 products then my expected value is the Order table will look like this:
id----product_id----size----color---price---+
---------------------------------------------
1 1 abc xyz 123
---------------------------------------------
2 2 abc2 xyz2 456
---------------------------------------------
3 3 aaa bbb 789
Thank for your help!

DB:
Order:
user_id
created_at
...
orderProducts:
price
color
size
order_id (relation)
product_id (relation)
...
View
<form action="{{route('order.store')}}" method="post">
#csrf
#foreach ($cart as $ct)
<input type="text" name="products[]" value="{{$ct->product_id}}" hidden>
<input type="text" value="{{$ct->color}}" name="color[]" >
<input type="text" value="{{$ct->size}}" name="size[]" >
<input type="text" value="{{$ct->price}}" name="price[]" >
#endforeach
<button type="submit">submit</button>
</form>
controller function store
$order= new Order;// change the model here
// .. complete your information's like user id or created_at
$order->save();
foreach($request->products as $key=>$product_id)
{
$product = Product::findOrFail($product_id); // validations the product id
// get your information's from db (color,size,price) don't trust get information's from user .
// $product->price , $product->color .... or get from cart
//from cart direct $color[$key] or $price[$key] or $size[$key] "I don't recomend to use this point"
// must be create new table
$orderProducts=new orderProducts; // create new table ordersProducts
$orderProducts->price = $product->price;
// .. complete your information's
$orderProducts->order_id = $order->id; // primary key
$orderProducts->product_id= $product->id;
$orderProducts->save();
}
Notice:
- You need to use try-catch to record info in order if fail in the step "findOrFail" or change to find and then if product not found in the table then record order not complete and show an error to the user

My Answer is quite similar to above answer but i would just like to put a different approach here with Database Transaction, Try Catch & Bulk Insert(to prevent placing queries in loop)
try {
DB::begintransaction();
$order = Order::create($orderData); // change the model here
$orderProductsData = [];
foreach($request->products as $product_id) {
$product = Product::find($product_id); // validations the product id
$orderProductsData[] = $tmpData = [
'price' => $product->price,
'order_id' => $order->id,
'product_id' => $product->id;
];
// must be create new table
// You can also store this way, but its still in loop so putting under comment.
// $orderProducts = orderProducts::create($tmpData);
}
orderProducts::insert($orderProductsData);
DB::commit();
} catch (Exception $e) {
DB::rollback();
thow $e; // modify with, How you handle your error response.
}
Again, Above answer is totally correct, However just putting a different approach, which i believe little more optimised way.

Related

How does a Laravel model get a "required" data? New column, adding another column's data

Still new to laravel, learning how the $request interacts with create.
here is my form for two of my variables for context:
<form method="POST" id="postForm">
{{-- #csrf --}}
<input type="hidden" id="id_hidden" name="id" />
<div class="form-group">
<label for="title"> Title <span class="text-danger">*</span></label>
<input type="text" name="title" id="title" class="form-control">
</div>
<div class="form-group">
<label for="category_description"> Description <span class="text-danger">*</span></label>
<textarea name="category_description" id="category_description" class="form-control"></textarea>
</div>
</form>
controller:
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'category_description' => 'required',
]);
$post = HmsBbrCategory::create($request->all());
if(!is_null($post)) {
return response()->json(["status" => "success", "message" => "Success! post created.", "data" => $post]);
}
else {
return response()->json(["status" => "failed", "message" => "Alert! post not created"]);
}
}
model:
protected $table = 'hms_bbr_category';
protected $fillable = [
"category_id", "title", "category_description", "category_description_2"
];
my title and category_description is inserting fine with an auto incremented id column. What I am trying to do is just to add 2 columns: category_id and category_description_2 that just copies the value inserted by id and category_description
Question:
how does 'required' retrieve the data from the form? I would like to have the same data thats taken and adding it to my two new columns. I am aware that I cannot just simple add 'category_description_2' => 'required',because this won't get an existing data.
so basically
$id = id
$category_id = id
$title = title
$category_description = category_description
$category_description_2 = category_description
1
Here is my table for reference. This form was given to me and I want to understand to know more about Laravel, thanks for reading and I hope I can get some suggestions on what to add.
You are running ->validate([]) on the $request variable which takes all of the information that is laravel puts together during the post request. If you do
dd($request->all()); you will be able to see all of the data that is passed from the form that you can run different validate rules on.
If you would like to add other data into your $request variable in order to save it to your model, you can always just add it to the $request array like so: $request['variable_1'] = 'data for variable one' and so on
Since I see that you have category_id that you would like to reference in your saved record, I would suggest you create a relation in your HmsBbrCategory model and the parent model that category_id belongs to. This will help you keep the integrity of your database in tact.
As another option, you can structure your url in such a way that passes the category_id to your store method in the controller. You will then need to find that category id and make sure it exists and save it via the relation that you created:
public function store (Request $request, $category_id){
$main_category = Category:find($category_id); //make sure it exists
$new_record = $main_category->exampleRelation()->save($request->all());
if(!$new_record){
return failed save
}
return successful save message
}
By doing the above, it will automatically insert the category_id into your saved record.
As another alternative, you could create a hidden field in your form that references category_id and other fields that you would like to add to your record on save. However, keep in mind which "sensitive" information you would like the users to see if someone decide to view source on the browser window.

Counting orders Laravel

I have a simple application which sum amount of my orders and payments only per same day and submit them in table. I have a drawer which starting every day and when finish the day I can submit total sum of day (orders,pay in/out) and at the next day I'm starting from begining with 0 cash again.
My question: Is that a possible to end my drawer and start it again in the same day with 0 cash multiple times per day?
Now if I start again I'm seeing all orders whose are already maked today.
My controller:
public function show($id)
{
$locations = Location::find($id)->orders()->whereDate('created_at', '=', Carbon::today()->toDateString()); //show orders
$wallets = Location::find($id)->locsales()->whereDate('created_at', '=', Carbon::today()->toDateString()); //show payments
$loc = Location::find($id); //to show location name
return view('location')
->with('locations', $locations)
->with('wallets', $wallets)
->with('loc', $loc);
}
Part of my view:
<div class="card-body">
<div class="form-group">
<div class="list-group-item">
<label for="location">Location: {{$loc->location_id}}</label>
<form method="post" action="/post_drawer">
#csrf
<input type="number" class="form-control" name="start_cash" id="start_cash" value="{{$wallets->sum('start_cash')}}" readonly>
<label for="info">Amount of orders(today):</label>
<input type="number" class="form-control" name="amount" id="amount" value="{{$locations->sum('total')}}" readonly>
Update 1: I added to orders table and to my view option to submit added_to_drawer field with boolean and now my controller is like that:
$locations = Location::find($id)->orders()->whereDate('created_at', '=', Carbon::today()->toDateString())->whereNull('added_to_drawer');
May be I'm doing something wrong but it doesn't work.
Update 2:I maked my controller to show only records with value 1 and now it's working correct.
$locations = Location::find($id)->orders()
->where('added_to_drawer', 1)
$affected = DB::table('orders')->whereid('location', $id)->update(array('added_to_drawer' => 0));
$affected = DB::table('wallets')->where('location_id', $id)->update(array('added_to_drawer' => 0));
But I have another problem. When I close my drawer he update(reset) all locations
drawer to 0.
For example - I want to update only this locations where name is New York but to be dynamically. Not like that: where('location','=','New York')
I tried it like this: where('location','=' $id) but it's doesn't work.

Magento 2 form mini filter where category ID in array

I am trying to use the following method to filter the category id on my mini form submit
<input type="hidden" name="cat" value="1">
But this only allows to filter by 1 category id, I need to be able to pass in an array of category ID's to the mini form. Is there anyway I can use a similar method to filter the search results by an array of category id's? Or can anyone point me in the right direction on how to achieve this?
You can use serialize() and base64_encode().
$cat_ids = array(1, 2, 3);
$post_cat_ids = base64_encode(serialize($cat_ids));
// Input field
<input type="hidden" name="cat" value="<?php echo $post_cat_ids; ?>">
On server side you can get back array:
$cat_ids = unserialize(base64_decode($_POST['cat']));
print_r($cat_ids);

How to give dynamic name in array in input field?

I have a form which will have dynamic value and it will check that property id and then save it to the database.
For example in my database there is a table with title having the id=1, type having the id=2, description having the id=3, and after the form is submitted it will check if the field is title or type or description and it will save it in database that is if it is title it will save value of field title with propertyid value 1.
<form method="post" action="something.php">
<input type="text" name="field[][title]" value="edison">
<input type="text" name="field[][type]" value="book">
<input type="text" name="field[][description]" value="some description">
</form>
it is not inputting normal array in php with using foreach, I am not understanding how to get the value inside the index of the array to check with the sql database, that is to check if the field[][title]" then title has id 1 and if the field is field[][description]" it will check the sql for the property id of description that is 3
You need to look at it in reverse.
You first need to query your database so that you have a mapping of which field associates with which ID.
Then, when your information is posted, you can iterate over that mapping, detect if they have been posted, and use them accordingly:
$mapping = loadFieldNamesToFieldId();
/*
mapping should look something like:
$mapping = [
'title' => 1,
'type' => 2
];
*/
foreach ($_POST as $field_name => $field_value) {
if (isset($mapping[$field_name]]) {
$id = $mapping[$field_name];
// at this point you know that the user submitted a field which
// had $field_value, and which ID it relates to in your database
}
}
At which point you can just format your form as so:
<input type="text" name="title" value="edison">
I found this answer and thought of posting this as this relates to the answer
foreach ($_POST as $param_name => $param_val)
{
echo "Param: $param_name; Value: $param_val<br />\n";
}

Update a database item with price incl/excl taxes depending on a radio button

I am making a kind of checkout form. At the top I have two radio buttons, one that should show prices without tax when clicked, and another to show prices when clicked.
<form id="f-p" method="post" action="#####">
<label for="exkl">Exkl. moms</label><input name="moms" id="exkl" type="radio"value="exkl" checked="checked"/>
<label for="inkl">Inkl. moms</label><input name="moms" id="inkl" type="radio" value="inkl"/>
</form>
Then I have prices below in tables. Those prices all come from a MySQL database. Now I can, separately, query the database for product IDs:
if($_POST['moms'] == "inkl") {
$inkl_query ="SELECT `product_id` FROM `######products_fieldvals` WHERE `fielddef_id`=4";
$iresult = mysql_query($inkl_query);
but I want to cycle through and compare product IDs between two tables, and if they match, to isert the price for that item from the first table into the second one, and to toggle back for the other radio. How can I do this? I want to use:
if($list1ID = $list2ID) {
INSERT INTO products(price)
SELECT value FROM products_fieldvals WHERE fieldval_id="4",
}
but that isn't working. Can someone please help?
if($list1ID == $list2ID) {
mysql_query("INSERT INTO products(price) SELECT value FROM products_fieldvals WHERE fieldval_id='4'");
}

Categories