I am working with a purchase ordering app. I have two tables, the orders table, and order_items. I would like to order_items to grab the id of orders which is in a single action. apology if I wasn't able to explain it clearly. here's my store function.
public function store(Request $request) {
$orders = $request->only(
'user_id',
'status_id',
'currency_id',
'company_id',
'purchase_no',
'notes',
'delivery_date',
'publish'
);
$orders['grandtotal'] = (float) str_replace(',', '', $request->grandtotal);
$orders = Orders::create($orders);
$input = $request->all();
for($i=0; $i<= count($input['quantity']); $i++) {
if(empty($input['quantity'][$i]) || !is_numeric($input['quantity'][$i])) continue;
$items = [
'order_id' => $input['order_id'][$i],
'product_id' => $input['product_id'][$i],
'product_code' => $input['product_code'][$i],
'product_name' => $input['product_name'][$i],
'cost' => $input['cost'][$i],
'quantity' => intval($input['quantity'][$i]),
'total_cost' => (float) str_replace(',', '', $input['total_cost'][$i]),
];
Orderitems::create($items);
}
return redirect()->route('orders.index');
}
what should I do to achieve this process? thank you so much in advance!
Just replace $input['order_id'][$i] with $orders->id, It might help you.
$items = [
'order_id' => $orders->id,
'product_id' => $input['product_id'][$i],
'product_code' => $input['product_code'][$i],
'product_name' => $input['product_name'][$i],
'cost' => $input['cost'][$i],
'quantity' => intval($input['quantity'][$i]),
'total_cost' => (float) str_replace(',', '', $input['total_cost'][$i]),
];
Related
i have an array with values that i am trying to insert it in the database, but when i use create() the values are inserted as null in database while if i use insert() the values insert correct.
This is the code from the controller
public function store(Request $request)
{
$request->validate([
'order_number' => 'required',
'client' => 'required',
'products' => 'required',
'amount' => 'required',
'description' => 'required',
]);
for($i = 0; $i < count($request->products); $i++)
{
$values[] = [
'order_number' => $request->order_number,
'client' => $request->client,
'products' => $request->products[$i],
'amount' => $request->amount[$i],
'description' => $request->description
];
}
Order::create($values);
return redirect('/')->with('msg', 'Order Saved successfully!');
}
and this is the code from the model
public $timestamps = true;
protected $fillable = [
'order_number',
'client',
'products',
'amount',
'description',
];
The names are the same and in the database, any reason why the values come null when i use create() method?
insert() method accepts multiple objects in form of arrays to be created, for example :
DB::table('users')->insert([
['email' => 'picard#example.com', 'votes' => 0],
['email' => 'janeway#example.com', 'votes' => 0],
]);
But create() method does not accept such structure. You cannot create multiple entries using this method. So in this case you either keep using insert(), either move your create() inside for loop.
Edit : createMany() works only on relationships, and apparently DB manipulation in loops is antipattern. In that case you can do something like this :
$created_at = now();
for($i = 0; $i < count($request->products); $i++)
{
$values[] = [
'order_number' => $request->order_number,
'client' => $request->client,
'products' => $request->products[$i],
'amount' => $request->amount[$i],
'description' => $request->description,
'created_at' => $created_at,
'updated_at' => $created_at,
];
}
Order::insert($values);
Hello i have this code in laravel controller and i get an error for a single value:
public function store(Request $request)
{
$values = [];
$request->validate([
'order_number' => 'required',
'client_id' => 'required|exists:clients,id',
'description' => 'required',
'products' => 'required|exists:products,id',
'amount' => 'required',
]);
$order = Order::create($request->all());
foreach ($request->products as $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount,
];
$amount = Product::find($product);
$total_value = $request->amount + $amount->amount; //the error happens here
$amount->update(['amount' => $total_value]);
}
$order->products()->attach($values);
return redirect('/')->with('msg', 'Order Saved successfully!');
}
All the values come except the $request->amount that comes as array and not as a single value in a row. This is the error i get:
Unsupported operand types: array + string
This is the product model:
protected $fillable = [
'name',
'price',
'amount',
];
public function orders()
{
return $this->belongsToMany(Order::class);
}
And this is dd($request->amount);
Assuming that $request->amount is directly related to $request->products with the index then you would either need to combine products and amount before you send the request or iterate over products with the index.
foreach ($request->products as $index => $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount[$index], //Reference via index
];
$amount = Product::find($product);
$total_value = $request->amount[$index] + $amount->amount; //Also here
}
}
I am adding order to database. It works like this: When ordering is clicked, the order is created in the Order table, at the same time the product items are also added to the OrderItem table, via the order_id foreign key. But I don't know how to get the order_id, because it is added at the same time, and the Order id is increments.
public function save(array $data, int $id = null){
$idCurrent = Auth::id();
$orderItems = $data['orderItems'];
//add to Order
Order::updateOrCreate(
[
'id' => $id
],
[
'user_id' => $idCurrent,
'shipping_fee' => $data['shipping_fee'],
'total' => $data['total'],
'payment' => $data['payment'],
'status_id' => 1,
]
);
//add to OrderItem
foreach($orderItems as $item){
OrderItem::Create([
'order_id' => 222, //=> ?????????????
'product_id' => $item -> product_id,
'quantity' => $item->quantity,
]);
}
return true;
}
$order = Order::updateOrCreate(
[
'id' => $id
],
[
'user_id' => $idCurrent,
'shipping_fee' => $data['shipping_fee'],
'total' => $data['total'],
'payment' => $data['payment'],
'status_id' => 1,
]
);
//add to OrderItem
foreach($orderItems as $item){
OrderItem::Create([
'order_id' =>$order->id
'product_id' => $item -> product_id,
'quantity' => $item->quantity,
]);
}
return true;
Avoid multiple call to databases.
When you create order with
$order = Order::updateOrCreate(
[
'id' => $id
],
[
'user_id' => $idCurrent,
'shipping_fee' => $data['shipping_fee'],
'total' => $data['total'],
'payment' => $data['payment'],
'status_id' => 1,
]
);
next you should is to send just one request to database with
// create batch array
$insertOrderItems = [];
foreach($orderItems as $item){
$insertOrderItems[] = [
'product_id' => $item->product_id,
'quantity' => $item->quantity,
];
}
// insert all at once in batch mode making just one call to database
$order->orderItems()->create($insertOrderItems);
Presuming you have sorted relations in Order and OrderItem models.
The validate() function from my sales controller seems not working, I am comparing it to my other controller, it looks like it should work but it is not. it looks like the validate() is being bypassed. here's my controller
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class SalesController extends Controller
{
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required',
'status_id' => 'required',
'currency_id' => 'required',
'company_id' => 'required',
'invoice_no' => 'nullable',
'notes' => 'nullable',
'admin_notes' => 'nullable',
'due_date' => 'nullable',
'publish' => 'nullable',
'product_id' => 'required|min:1',
'product_code' => 'required|min:1',
'product_name' => 'required|min:1',
'quantity' => 'required'
]);
$sales = $request->only(
'user_id',
'status_id',
'currency_id',
'currency_rate',
'due_date',
'company_id',
'invoice_no',
'notes',
'admin_notes',
'delivery_date',
'publish'
);
$sales['grandtotal'] = (float) str_replace(',', '', $request->grandtotal);
$sales['grandtotalcost'] = (float) str_replace(',', '', $request->grandtotalcost);
$sales = Sales::create($sales);
$input = $request->all();
for($i=0; $i<= count($input['quantity']); $i++) {
if(empty($input['quantity'][$i]) || !is_numeric($input['quantity'][$i])) continue;
$items = [
'sales_id' => $sales->id,
'product_id' => $input['product_id'][$i],
'product_code' => $input['product_code'][$i],
'product_name' => $input['product_name'][$i],
'price' => $input['price'][$i],
'cost' => $input['cost'][$i],
'quantity' => intval($input['quantity'][$i]),
'total_price' => (float) str_replace(',', '', $input['total_price'][$i]),
'total_cost' => (float) str_replace(',', '', $input['total_cost'][$i]),
];
Salesitems::create($items);
}
// $ponumbers = Ponumbers::create($request->only('purchase_no'));
$invnum = $request->all();
$invnumbers = new Invnumbers;
$invnumbers->sales_num = $invnum['invoice_no'];
$invnumbers->save();
if ($request){
Session::flash('message','Invoice was successfully added');
Session::flash('m-class','alert-success');
} else {
Session::flash('message','Data is not saved');
Session::flash('m-class','alert-danger');
return redirect()->route('sales.index');
}
return redirect()->route('sales.index');
}
}
My Blade
<input class="form-control autocomplete_txt product_name" type='text' data-type="product_name" id='product_name_1' name='product_name[]' for="1" readonly/>
#if ($errors->has('product_name')) <p class="help-block">{{ $errors->first('product_name') }}</p> #endif
if I submit my form with product name, instead of throwing error from validate,
By seeing your code, to me it seems your product_id should be an array. So the validation should be:
'product_id' => 'array|required|min:1',
'product_id.*' => 'required',
instead of
'product_id' => 'required|min:1',
Try to use $request->validate([... instead of $this->validate($request, [.... I'm not sure is there validate in your controller...
I have cart on my web store and so far everything works perfectly but I said when I try decrement the product quantity to product, the all product in my database will decrement Not just products in cart.
Here is my ordercontroller :
public function postOrder(Request $request) {
$validator = Validator::make($request->all(), [
'first_name' => 'required|max:30|min:2',
'last_name' => 'required|max:30|min:2',
'address' => 'required|max:50|min:4',
'address_2' => 'max:50|min:4',
'city' => 'required|max:50|min:3',
'state' => 'required|',
'zip' => 'required|max:11|min:4',
'full_name' => 'required|max:30|min:2',
]);
if ($validator->fails()) {
return redirect('/checkout')
->withErrors($validator)
->withInput();
}
$first_name = Input::get('first_name');
$last_name = Input::get('last_name');
$address = Input::get('address');
$address_2 = Input::get('address_2');
$city = Input::get('city');
$state = Input::get('state');
$zip = Input::get('zip');
$full_name = Input::get('full_name');
$user_id = Auth::user()->id;
$cart_products = Cart::with('products')->where('user_id', '=', $user_id)->get();
$cart_total = Cart::with('products')->where('user_id', '=', $user_id)->sum('total')
$charge_amount = number_format($cart_total, 2) * 100;
$order = Order::create (
array(
'user_id' => $user_id,
'first_name' => $first_name,
'last_name' => $last_name,
'address' => $address,
'address_2' => $address_2,
'city' => $city,
'state' => $state,
'zip' => $zip,
'total' => $cart_total,
'full_name' => $full_name,
));
foreach ($cart_products as $order_products) {
$order->orderItems()->attach($order_products->product_id, array(
'qty' => $order_products->qty,
'price' => $order_products->products->price,
'reduced_price' => $order_products->products->reduced_price,
'total' => $order_products->products->price * $order_products->qty,
'total_reduced' => $order_products->products->reduced_price * $order_products->qty,
));
}
// in the fact all product will decrement Not just products in cart
\DB::table('products')->decrement('product_qty', $order_products->qty);
Cart::where('user_id', '=', $user_id)->delete();
flash()->success('Success', 'Your order was processed successfully.');
return redirect()->route('cart');
}
I use program \DB::table('products')->decrement('product_qty', $order_products->qty);; for the decrement but in the fact all product will decrement Not just products in cart
The decrement you are using updates all records, as you have observed because you didn't constrain it to a specific record. You want to do this in your loop:
DB::table('products')
->where('id', '=', $order_products->product_id)
->decrement('product_qty', $order_products->qty);