public function goesWellWith(Request $request)
{
$seo_url = $request->seo_url;
$product = $this->product->getByAny('seo_url',$request->seo_url)->first();
$categories = $this->product->getProductCategories($product->id);
$category_ids = [];
$products = [];
if(count($categories) > 0){
$category_ids = array_column($categories, 'term_id');
}
if(count($category_ids) > 0){
$get_fillter_product = $this->product->getProductByFilter([
'recommended' => "on"
],$category_ids);
foreach($get_fillter_product as $single_product){
$categoryProductList = [
'title' => $single_product->title,
'sub_title' => $single_product->sub_title,
'first_image' => $single_product->first_image?$single_product->first_image->full_size_directory: null,
'second_image' => $single_product->second_image?$single_product->second_image->full_size_directory: null,
'seo_url' => $single_product->seo_url
];
$category_ids [] = $categoryProductList;
}
}
return response()->json(compact('category_ids'));
}
//
-
List item
when i hit the url in insomnia to check i got this ErrorException array_column() expects parameter 1 to be array, object given//
i got the error in this line of code
if(count($categories) > 0){
$category_ids = array_column($categories, 'term_id');
}
Try change your code from this
$categories = $this->product->getProductCategories($product->id);
To
$categories = $this->product->getProductCategories($product->id)->toArray();
Related
I'm an elementary web developer, I'm facing a problem. Please help me solve this. I'm creating both row and column dynamic. for save() is fine. But for update, only name is updated and other item
quantities cannot. Here is my codes.
//for save()
public function stockAdd(Request $request)
{
$validator = validator(request()->all(), ['stock_name' => 'required']);
if($validator->fails()) {
return back()->withErrors($validator);
}
$user_id = Auth::user()->user_id;
$stock_id = random_int(100000, 999999);
$stocks = new Stocks();
$stocks->stock_id = $stock_id;
$stocks->owner_id = $user_id;
$stocks->stock_name = request()->stock_name;
$stocks->my_stock = 0;
$stocks->disable = 0;
$stocks->save();
$brands = Brands::all();
$products = Products::all();
foreach ($brands as $brand){
foreach ($products as $product){
if($product['brand_id'] == $brand['id']){
$product_id = $product->product_id;
$stockitems = new StockItems();
$stockitems->stock_id = $stock_id;
$stockitems->product_id = $product->product_id;
$stockitems->owner_id = $user_id;
if(request()->$product_id > 0){
$stockitems->count = request()->$product_id;
}else{
$stockitems->count = 0;
}
$stockitems->save();
}
}
}
return redirect()->back()->with('successAddMsg','Successfully Added');
}
//for update()
public function stockUpdate(Request $request, $id)
{
$validator = validator(request()->all(), ['stock_name' => 'required']);
if($validator->fails()) {
return back()->withErrors($validator);
}
$stock = Stocks::findOrFail($id);
$stock->stock_name = request()->stock_name;
$stock->my_stock = 0;
$stock->disable = 0;
$stock->update();
$brands = Brands::all();
$products = Products::all();
foreach ($brands as $brand){
foreach ($products as $product){
if($product['brand_id'] == $brand['id']){
$product_id = $product->product_id;
//dd($product_id);
$stockitemitems = DB::table("stock_items")->select("*")->where("owner_id",Auth::user()->user_id)->where("stock_id",$stock->stock_id)->get();
$stockitems->count = $request->input($product_id);
$stockitems->update();
}
}
}
return redirect(route('user.stock-list'))->with('successAddMsg','Successfully Added');
}
The problem shows like this "Creating default object from empty value"
I initialize session('idUser') on successful login. But it is always null when using http get.And Auth::id() is always null as well.
class CartService {
public function getAll($orderBys = [], $limit = 2) {
$idCurrent = session('idUser'); // => null
//$idCurrent = Auth::id(); => null
$query = Cart::query() -> where('user_id',$idCurrent);
if($orderBys){
$query->orderBy($orderBys['column'], $orderBys['sort']);
}
return $query-> paginate($limit);
}
}
//Call API (127.0.0.1:8000/api/cart)
public function index(Request $request)
{
$carts = Http::get("http://127.0.0.1:8000/api/cart");
$carts = json_decode($carts, true);
$cartArr = $carts['cartArr'];
//convert
$cart = array();
for($i = 0; $i < count($cartArr); $i++)
{
$object = new Cart();
foreach ($cartArr[$i] as $key => $value)
{
$object->$key = $value;
}
array_push($cart,$object);
}
dd($cart); // => result = []
}
I have very complex functions in laravel APIs ( called from Mobile App).
The sample function is given below.
If someone can help to improve the code structure.
I wish to know the best practices in handling multiple transactions in a single API. Because if I move each table's entry to separate function - how do I handle errors of each one? Ex: when the quantity is not set in $request model
SUMMARY:
Can someone please break it into smaller functions?
.... Because I don't know how/where to break it into smaller ones.
public function placeOrder(Request $request)
{
$this->validate($request, [
'addressId' => 'required'
]);
$userId = Auth::user()->id;
$itemList = array();
$deliveryCharge = Store::first()->delivery_charge;
// $deliveryCharge = Store::findOrFail($request->header('StoreId'))->delivery_charge;
$total = $deliveryCharge;
$cod = $request->cod;
$useBalanceFirst = $request->useBalanceFirst;
$addressId = $request->addressId;
$list = $request->list;
$cost = 0;
// fetch all items using id in request
foreach ($list as $orderItemFromRequest) {
if (!isset($orderItemFromRequest['id']))
return $this->error("Invalid item selected");
$itemFromDB = Item::find($orderItemFromRequest['id']);
if (!isset($orderItemFromRequest['quantity']))
return $this->error("Please enter quantity for {$itemFromDB->name}");
$qty = $orderItemFromRequest['quantity'];
if ($qty > 0.0) {
if ($itemFromDB == null || $itemFromDB->available == false)
return $this->error("Invalid item selected");
$itemFromDB->quantity = $qty;
$total += ($itemFromDB->sell_rate * $itemFromDB->quantity) / $itemFromDB->rate_unit_multiple;
$cost += ($qty * $itemFromDB->purchase_rate) / $itemFromDB->rate_unit_multiple;
array_push($itemList, $itemFromDB);
}
}
if (count($itemList) == 0) {
return $this->error("At least 1 item is needed to place the order");
}
// check user balance
$user = User::findOrFail($userId);
// if balance < total -> throw error
if ($cod != true && $user->balance < $total) return $this->error("Insufficient Balance. Please recharge your wallet or use C.O.D.", 403);
$order = new Order();
$order->user_id = $user->id;
$order->total = $total;
$order->delivery_charge = $deliveryCharge;
$order->purchase_rate = $cost;
// because in-case user changes his/her name in future - the order should have the historical name & number
$order->customer_name = $user->name;
$order->customer_contact = $user->contact_no;
$order->address_id = $addressId;
if ($cod == true) {
if ($useBalanceFirst == true) {
if ($user->balance < $order->total)
$order->amount_due = $order->total - $user->balance;
else
$order->amount_due = 0;
} else {
$order->amount_due = $order->total;
}
} else
$order->amount_due = 0;
$ordertransaction = new OrderTimeLine();
$ordertransaction->created_by = Auth::user()->id;
DB::transaction(function () use ($order, $itemList, $user, $ordertransaction) {
// insert 1 entry into orders
$order->save();
$order->refresh();
$newOrderItemList = array();
// insert N entries for Items
foreach ($itemList as $requestItem) {
$item = new OrderItem();
$item->order_id = $order->id;
$item->item_id = $requestItem->id;
$item->item_name = $requestItem->name;
$item->sell_rate = $requestItem->sell_rate;
$item->purchase_rate = $requestItem->purchase_rate;
$item->quantity = $requestItem->quantity;
$item->quantity_unit = $requestItem->unit;
$item->rate_unit_multiple = $requestItem->rate_unit_multiple;
if ($requestItem->remaining_stocks <= 0) {
$item->purchase_rate_qty = 0;
} else if ($requestItem->remaining_stocks < $requestItem->quantity) {
$item->purchase_rate_qty = $requestItem->remaining_stocks;
} else
$item->purchase_rate_qty = $requestItem->quantity;
$item->save();
$item->refresh();
$requestItem->remaining_stocks = $requestItem->remaining_stocks - $requestItem->quantity;
// update remaining QTY and cost price
unset($requestItem->quantity);
if ($requestItem->remaining_stocks <= $requestItem->alert_stocks) {
// send notification
NotificationController::notifyAdminAboutStocks($requestItem);
}
$requestItem->save();
array_push($newOrderItemList, $item);
}
$order->items = $newOrderItemList;
// deduct balance from user table
$user->balance = $user->balance - $order->total + $order->amount_due;
$user->save();
$balanceAffected = 0 - $order->total + $order->amount_due;
// enter transaction in wallet_transaction table
if ($balanceAffected != 0) {
$transaction = new WalletTransaction();
$transaction->user_id = $user->id;
$transaction->amount = $balanceAffected;
$transaction->type = WALLET_ORDER_PLACED;
$transaction->order_id = $order->id;
$transaction->save();
}
$ordertransaction->status = $order->status;
$ordertransaction->order_id = $order->id;
$ordertransaction->save();
});
NotificationController::notifyAdminAboutOrder($user, $order);
return $this->success(["balance" => $user->balance, "order" => $order]);
}
You are handling too many work in the controller function.
First of all I suggest to make full use of Laravel Validation functionality. then use Laravel Collection to make your code more readable and compact. I have refactored your function as how I usually handle.
public function placeOrder(Request $request)
{
$data = $request->validate([
'addressId' => 'required',
'cod' => 'required|boolean',
'useBalanceFirst' => 'required|boolean',
'list' => 'required|array',
'list.*.quantity' => 'required|numeric',
'list.*.id' => ['required', 'numeric', Rule::exists('items')->where(function ($query) {
$query->where('available', true);
})],
]);
$user = Auth::user();
$orderItems = collect($data['list'])->map(function($listItem){
$item = Item::find($listItem['id']);
$orderItem = new OrderItem([
'item_id' => $item->id,
'item_name' => $item->name,
'sell_rate' => $item->sell_rate,
'purchase_rate' => $item->purchase_rate,
'quantity' => $listItem['quantity'],
'quantity_unit' => $item->quantity_unit,
'rate_unit_multiple' => $item->rate_unit_multiple,
]);
if ($item->remaining_stocks <= 0) {
$orderItem->purchase_rate_qty = 0;
} else if ($item->remaining_stocks < $orderItem->quantity) {
$orderItem->purchase_rate_qty = $item->remaining_stocks;
} else
$orderItem->purchase_rate_qty = $orderItem->quantity;
return $orderItem;
});
$total = $orderItems->sum(function($item){
return ($item->sell_rate * $item->quantity) / $item->rate_unit_multiple;
});
$cost = $orderItems->sum(function($item){
return ($item->quantity * $item->purchase_rate) / $item->rate_unit_multiple;
});
$deliveryCharge = Store::first()->delivery_charge;
$total += $deliveryCharge;
// if balance < total -> throw error
if (!$data['cod'] && $user->balance < $total)
{
return $this->error("Insufficient Balance. Please recharge your wallet or use C.O.D.", 403);
}
$order = new Order([
'user_id' => $user->id,
'total' => $total,
'delivery_charge' => $deliveryCharge,
'purchase_rate' => $cost,
// because in-case user changes his/her name in future - the order should have the historical name & number
'customer_name' => $user->name,
'customer_contact' => $user->contact_no,
'address_id' => $data['addressId'],
]);
if ($data['cod']) {
if ($data['useBalanceFirst']) {
if ($user->balance < $order->total)
$order->amount_due = $order->total - $user->balance;
else
$order->amount_due = 0;
} else {
$order->amount_due = $order->total;
}
} else
{
$order->amount_due = 0;
}
DB::transaction(function () use ($order, $orderItems, $user) {
// insert 1 entry into orders
$order->save();
$order->items->saveMany($orderItems);
// deduct balance from user table
$user->balance = $user->balance - $order->total + $order->amount_due;
$user->save();
$ordertransaction = OrderTimeLine::create([
'created_by' => $user->id,
'status' => $order->status,
'order_id' => $order->id,
]);
});
return $this->success(["balance" => $user->balance, "order" => $order]);
}
As you have noticed I have removed notification and user wallet transaction code as these should be updated asynchronously with no impact on your user experience. I suggest you take a look at Laravel Events.
I am working on a web application, which searches for places/locations via /search route. On /search route it displays all the matched/searched locations BUT the locations are array based i want to paginate through it which i did but now the problem arises in the view. In the view i used
{!! $father->render() !!}
which renders the pagination but when i try to go to the 2nd it doesn't work.
Controller Code
{
public function paginate($items,$perPage)
{
$pageStart = \Request::get('page', 1);
// Start displaying items from this number;
$offSet = ($pageStart * $perPage) - $perPage;
// Get only the items you need using array_slice
$itemsForCurrentPage = array_slice($items, $offSet, $perPage, true);
return new LengthAwarePaginator($itemsForCurrentPage, count($items), $perPage,Paginator::resolveCurrentPage(), array('path' => Paginator::resolveCurrentPath()));
}
/**
* When user submit the search form it will return all the locations.
*
* #return locations collection
*/
public function postSearch(Request $request)
{
$categoryid = $request->category_id;
$locationid = $request->location_id;
$validator = \Validator::make($request->all(), [
'category_id' => 'required',
'location_id' => 'required',
],
[
'category_id.required' => 'Select Category',
'location_id.required' => 'Select Location',
]);
if($validator->fails()) {
return back()->withInput()->withErrors($validator->errors());
}else{
$category = Category::where('id', $categoryid)->first();
if(!$category->locations->isEmpty()) {
$cities = Location::where('id', $locationid)->pluck('city');
$cityname = $cities[0];
$alllocations = [];
$ratecards = [];
$father = [];
$i = 0;
$filteredlocations = $category->locations->where('city', $cityname)->all();
foreach($filteredlocations as $location){
$alllocations[$i] = $location->getaddetails;
$ratecards[$i] = $location->ratecard;
$father[$i]['ad'] = $alllocations[$i];
$father[$i]['rate'] = $ratecards[$i];
$i++;
}
$perPage = 4;
$father = AdSearchController::paginate($father, $perPage);
$nothing = 1;
return view('ads', compact('father','nothing'));
}else {
//flag
$nothing = 0;
return view('ads', compact('nothing'));
}
}
}
}
Route::resource('/search', 'AdSearchController#postSearch'); This is the route.We are searching on this route.
I want to insert multiple records in my database using Laravel, however when i insert it, it only gives me one record in the database
Here's my Controller
public function postCreateAttendance()
{
$validate = Validator::make(Input::all(), array(
'status' => 'required'
));
if ($validate->fails())
{
return Redirect::route('viewStudent')->withErrors($validate)->withInput();
}
else
{
foreach(User::all() as $user):
foreach(User::whereRaw('isTeacher = "0" and isAdmin = "0"')->get() as $student)
foreach(User::whereRaw('isTeacher = "1" and isAdmin = "0"')->get() as $teacher)
//$users[$user->id]=$user->firstname;
$attendance = new Attendance();
$attendance->status = Input::get('status');
$attendance->comment = Input::get('comment');
$attendance->student_id = $student->id=$student->id;
$attendance->student_firstname = $student->id=$student->firstname;
$attendance->student_lastname = $student->id=$student->lastname;
$attendance->teacher_id = $teacher->id=$teacher->id;
$attendance->teacher_firstname = $teacher->id=$teacher->firstname;
$attendance->teacher_lastname = $teacher->id=$teacher->lastname;
if($attendance->save())
{
return Redirect::route('viewStudent')->with('success', 'ATTENDANCE HAS BEEN RECORDED!');
}
else
{
return Redirect::route('viewStudent')->with('fail', 'An error occured while creating the attendance.');
}
endforeach;
}
}
How can i save multiple records? Please help Thank You ^_^
The issue is that you are returning during the foreach loop - so only one record is processed. You need to process all the records, then return the route.
Here is some refactoring of your code
public function postCreateAttendance()
{
$validate = Validator::make(Input::all(), array(
'status' => 'required'
));
if ($validate->fails()) {
return Redirect::route('viewStudent')->withErrors($validate)->withInput();
}
foreach(User::where('isTeacher', '0')->where('isAdmin', '0')->get() as $student) {
foreach(User::where('isTeacher', '1')->where('isAdmin', '0')->get() as $teacher) {
$attendance = new Attendance();
$attendance->status = Input::get('status');
$attendance->comment = Input::get('comment');
$attendance->student_id = $student->id;
$attendance->student_firstname = $student->firstname;
$attendance->student_lastname = $student->lastname;
$attendance->teacher_id = $teacher->id;
$attendance->teacher_firstname = $teacher->firstname;
$attendance->teacher_lastname = $teacher->lastname;
$attendance->save();
}
}
return Redirect::route('viewStudent')->with('success', 'ATTENDANCE HAS BEEN RECORDED!');
}
Edit: I've removed the first foreach(User::all() as $user): - because at the moment, in your code, it does nothing...?