Format array output to be readable by chartjs in Laravel - laravel

This is my query to get the product name and total quantity sold.
$prd = DB::table('order_details')
->join('products', 'order_details.product_id', '=', 'products.id')
->select('products.name', DB::raw('SUM(quantity) as quantity'))
->groupBy('products.name')
->orderBy('quantity', 'desc')
->get();
return $prd;
This is the output.
[
{
"name": "PINK",
"quantity": "22"
},
{
"name": "WHITE",
"quantity": "14"
},
{
"name": "RED",
"quantity": "13"
}
]
But I need it to be in this format. For it to work with chartjs.
{
"PINK": 22,
"WHITE": 14,
"RED": 13
}
This is what I've so far. I tried to use collection map. But I'm not sure how to return the quantity portion. Any pointers?
return $prd->groupBy('name')->map(function ($item, $key) {
return ''; // what should I return here to get the qty?
});
Current half baked output
{
"PINK": "",
"WHITE": "",
"RED": "",
}

You can use pluck() instead of get() for this:
$prd = DB::table('order_details')
->join('products', 'order_details.product_id', '=', 'products.id')
->select('products.name', DB::raw('SUM(quantity) as quantity'))
->groupBy('products.name')
->orderBy('quantity', 'desc')
->pluck('name', 'quantity');

Related

Laravel mapWithKeys() returns single value

In laravel I'm getting products array that looks like this
dd($activity->load('products'));
"products": [
{
"id": 1,
"pivot": {
"activity_id": 1,
"product_id": 10,
"quantity": 16
}
},
{
"id": 2,
"pivot": {
"activity_id": 1,
"product_id": 11,
"quantity": 20
}
}
]
I want to get an array of objects and pluck only the pivot.product_id and pivot.quantity from the products array
Expected result:
"selected_products": [
{
"id": 10,
"quantity": 16
},
{
"id": 11,
"quantity": 20
}
]
What I tried
return $activity
->load('products')
->products()
->get()
->mapWithKeys(function ($product, $key) {
return ['id' => $product->pivot->product_id, 'quantity' => $product->pivot->quantity];
});
Result
{
"id": 10,
"quantity": 16
}
There are 2 problems on your code.
First, load('products') is redundant. You cam simple call $activity->products. Or if you need filter on the products , use $activity->products()->where(...)->get()
Second, you should use map for indexed array. mapWithKeys is using for associative array.
return $activity->products
->map(function ($product, $key) {
return ['id' => $product->pivot->product_id, 'quantity' => $product->pivot->quantity];
});

Is it possible to apply condition inside the map function of Laravel?

I wanted to apply some condition in foodOrders. Is it possible to apply condition inside map function that acts as where $foodOrder->foodOrders->where('invoice_id',null)->get();
public function getTableList(Request $request){
$skip =$request->skip;
$limit=$request->limit;
$totaltable = Table::get()->count();
$table = Table::skip($skip)->take($limit)->orderBy('id', 'DESC')->get();
$table->map(function($foodOrder){
$foodOrder->foodOrders;
});
}
Below is the output that this query returns. But I only want the data with null invoice_id
{
"success": true,
"message": "Lists of Table.",
"data": [
{
"id": 2,
"table_number": "TN02",
"food_orders": [
{
"id": 16,
"food_items_id": 1,
"table_id": 2,
"invoice_id": null,
"quantity": 2,
"price": "2000.00"
},
{
"id": 17,
"food_items_id": 2,
"table_id": 2,
"invoice_id": null,
"quantity": 3,
"price": "150.00"
}
]
},
{
"id": 1,
"table_number": "TN01",
"created_at": "2020-10-25 10:44:31",
"updated_at": "2020-10-25 10:44:31",
"food_orders": [
{
"id": 14,
"food_items_id": 1,
"table_id": 1,
"invoice_id": 39,
"quantity": 1,
"price": "2000.00"
}
]
}
]
}
Not the best approach, bu this should do the trick
$table->map(function($foodOrder){
$foodOrder->foodOrders=$foodOrder->foodOrders()->where('invoice_id',null)->get();
});
Note the scopes, you need them to apply where condition. And we say = so the further changes are propagated.
I think what you need to use is a filter and not a map. Or am I wrong ?
You can filter out the whitelisted records for the food_orders.
$table->map(function($record){
$record->food_orders = collect($record->food_orders)
->filter(fn($foodOrder) => is_null($foodOrder->invoice_id));
return $record;
});
From the output data you have shown above it seems that the food_orders is a hasMany relation on the model, so it would be easy to filter out the relation when eager loading
Assuming that Table model has a relation defined for food_orders
class Table extends Model
{
public function food_orders()
{
return $this->hasMany(FoodOrder::class);
}
//... rest of the class code
}
You can constrain the related models when eager loading
$table = Table::with([
'food_orders' => fn($query) => $query->whereNull('invoice_id')
])
->skip($skip)
->take($limit)
->orderBy('id', 'desc')
->get();

Laravel : Search Query filter

I have searchDetails array in my search. I have done all other search and get data on filter, Problem is that when i search with stone_min, stone_max I get data if there is only one searchDetails array, if there is two data it is return null. How can i do this ? I want search with stone_min, stone_max for particular product_id.
what i try :
Example for data to search :
{
"limit": 1000,
"offset":0,
"user_id": "",
"min_price": "",
"max_price": "",
"searchDetails": [
{
"product_id": "1",
"attributeId": [],
"is_exclude": "no",
"stone_min": "5",
"stone_max": "15"
},
{
"product_id": "2",
"attributeId": [],
"is_exclude": "no",
"stone_min": "100",
"stone_max": "500"
}
]
}
My query for getting all data
$searchablePost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->whereIn('product_id', $userApprovalProductIDs)
->where('status', 'Active')
->whereIn('demand_or_supply', $demand_or_supply);
Search for min-max stone :
if (count($searchDetails) > 0) {
$j = 0;
foreach ($searchDetails as $value) {
if (strtolower(trim($value['is_exclude'])) == "no") {
$searchablePost = $searchablePost->where(function ($query) use ($value) {
if ($value['stone_min'] && $value['stone_max']) {
if (isset($j) && $j == 0){
$query->where('stone_min', '>=', $value['stone_min'])->where('stone_max', '<=', $value['stone_max'])->where("product_id", (int)$value['product_id']);
} else {
$query->where('stone_min', '>=', $value['stone_min'])->where('stone_max', '<=', $value['stone_max'])->where("product_id", (int)$value['product_id']);
}
}
});
}
}
}
$searchedPost = $searchablePost->offset($offset)->limit($limit)->orderBy('id','desc')->get();
If you want to search between stone_min and stone_max for particualar product then do:
$request = json_decode($request->searchDetails, true);
$stoneMinMax = collect($request)->pluck('stone_min', 'stone_max');
Product::where(function($q) use($productId) ($stoneMinMax){
$q->where('product_id', $productId)
->whereBetween('stone_column', $stoneMinMax->toArray());
})->get();

Related $query->with but "pick properties as"

I am using Laravel 5.5.13.
I am trying to fetch all Extensions but with certain extra properties based on their relations.
My goal is to get data like this, I am trying to get the latest_comment_date, thumbs_count, and thumbs_yes_count:
[
{
"id": 3,
"name": "Pull Refresh",
"created_at": "2017-11-10 06:04:44",
"updated_at": "2017-11-10 06:04:44",
"latest_comment_date": "2017-11-10 05:46:25",
"thumbs_count": 10,
"thumbs_yes_count": 2
}
]
I tried this:
return Extension::with([
'comments' => function($query) { // rename to 'latest_comment_date'
$query->orderBy('created_at', 'desc')->take(1);
},
'thumbs' => function($query) { // rename to 'thumbs_count'
$query->count();
},
'thumbs' => function($query) { // rename to 'thumbs_yes_count'
$query->where('like', '=', true)->count();
}
])->get();
This gives me data like this:
[
{
"id": 3,
"name": "Pull Refresh",
"created_at": "2017-11-10 06:04:44",
"updated_at": "2017-11-10 06:04:44",
"comments": [
{
"id": 10,
"body": "heck ya baby",
"displayname_id": 2,
"extension_id": 3,
"created_at": "2017-11-10 18:31:31",
"updated_at": "2017-11-10 18:31:31"
}
],
"thumbs": []
}
]
May you please help me to "pick as" stuff as I showed at top most?
For counting you should use withCount like so:
return Extension::withCount(
'thumbs',
'thumbs as thumbs_yes_count' => function($query) {
$query->where('like', '=', true);
})->get();
Reference: Counting related models
And for taking latest comment, you should create extra relationship like so:
public function latestComment()
{
return $this->hasOne(Comment::class)->orderBy('created_at', 'desc');
}
so the whole code would look like this:
return Extension::with('latestComment')->withCount(
'thumbs',
'thumbs as thumbs_yes_count' => function($query) {
$query->where('like', '=', true);
})->get();

need to implement array push in forloop

----------------------Code --------------------------
public function event_requests(){
$Uid = Input::get('Uid');
$token = Input::get('token_code');
$time = Input::get('time');
if(App_user::where('ID', '=', $Uid)->where('token_code', '=', $token)->count() > 0){
$result = DB::table('Ball_invites')
->join('Ball_users','Ball_users.ID', '=', 'Ball_invites.people')
->select('Ball_users.*', 'Ball_invites.Eid')
->Where('Ball_users.Pid', '=', $Uid)
->orWhere('Ball_users.ID', '=', $Uid)
->get();
foreach ($result as $val){
$eis[] = $val->Eid;
$eids = array_unique($eis);
}
$event = DB::table('Ball_event')->whereIn('ID', $eids)->get();
$resultdataa = array();
foreach($result as $new){
$resultdataa[$new->Eid] = $new;
}
$resultdata = json_decode(json_encode($resultdataa), true);
$data = array();
foreach($event as $key){
$data[$key->ID] = $key;
}
$dataa = json_decode(json_encode($data), true);
$final = array();
foreach($dataa as $key2=>$val2){
foreach($resultdata as $key1=>$val1){
if($key2 == $key1){
$arrs[] = $val2;
$arrss[] = $val1;
print_r($val1);
}
}
}
return Response::json(array('status'=>200,'result'=>$final));
} else {
return Response::json(array('status'=>'401','msg'=>'session expired'));
}
}
--------------------- Need Record like this ----------------------
Editor Note: the data structure below looks like it is desired to be JSON,
but I'm not sure what to make of the nested array in a bad location.
{
"status": 200,
"result": [
{
"ID": 63,
"Uid": 86,
"event_type": 1,
"event_title": "Testing",
"event_location": "Home",
[
{
"ID": 141,
"Pid": 139,
"fname": "Veronica",
"lname": "khiwani",
"nick_name": "Ronnie",
},
{
"ID": 141,
"Pid": 139,
"fname": "Veronica",
"lname": "khiwani",
"nick_name": "Ronnie",
}
]
},
{
"ID": 64,
"Uid": 139,
"event_type": 2,
"event_title": "cricket match",
"event_location": "london",
}
]
}

Resources