Laravel Order By returns weird order - laravel

Hello everyone i have some information and i want to order them by the bill number
here is the array of data
[
{
"id": 162,
"bill_number": "9",
"created_at": "2020-09-15T16:21:47.000000Z",
"updated_at": "2020-09-15T16:28:40.000000Z"
},
{
"id": 161,
"bill_number": "8",
"created_at": "2020-09-15T16:06:56.000000Z",
"updated_at": "2020-09-15T16:07:09.000000Z"
},
{
"id": 164,
"bill_number": "10",
"created_at": "2020-09-15T16:28:51.000000Z",
"updated_at": "2020-09-15T16:29:24.000000Z"
},
{
"id": 151,
"bill_number": "1",
"created_at": "2020-09-15T15:18:47.000000Z",
"updated_at": "2020-09-15T15:19:13.000000Z"
}
]
basically its a punch of bills
i am retrieving them like this
$paid_bills = Bill::where([
['grand_total' , '!=' , 'null'],
['status' , 'payed']
])->orderBy('bill_number' , 'desc')
->get();
the what i am getting is like this
9
8
10
1
the simple question is why it is ordering it like this and how to fix it.
Thanks for your time
Note: i removed non-relevant data to save time

you can use orderByRaw
and you can convert string column to integer by multiple it by 1 ...
$paid_bills = Bill::where([
['grand_total' , '!=' , 'null'],
['status' , 'payed']
])->orderByRaw('bill_number*1 desc')
->get();

Your bill_number is currently string. To order them in DESC, you should use them as integer.
Use "bill_number": 9, instead of "bill_number": "9", on your bills, and apply this to all of them.
Remove the quotation mark.

Related

Laravel, get relation row instead of id

I want to get author row instead of author_id. I could this with add collection and change one by one but has Laravel any function for this? Well, I want make this one line
Can i use something like this
Book::where('id',$bid)->with('author')->first('author_id AS author'); //Changes only coulmn name :(
model
public function author()
{
return $this->hasOne(Author::class,'id','author_id');
}
query
Book::where('id',$bid)->with('author')->first()
Output
{
"id": 1,
"name": "Book 1",
"author_id": 3,
"category_id": 2,
"level_id": 1,
"book_language_id": 1,
"book_length": 0,
"img": "book1.png",
"summary": "Summary 1",
"rate_avg": "2.75",
"created_at": "2022-03-04T18:46:32.000000Z",
"updated_at": "2022-03-04T18:52:28.000000Z",
"author": {
"id": 3,
"name": "Author 3",
"created_at": "2022-03-04T18:46:32.000000Z",
"updated_at": "2022-03-04T18:46:32.000000Z"
}
}
Want
{
"id": 1,
"name": "Book 1",
"author": {
"id": 3,
"name": "Author 3",
"created_at": "2022-03-04T18:46:32.000000Z",
"updated_at": "2022-03-04T18:46:32.000000Z"
},
"category_id": 2,
"level_id": 1,
"book_language_id": 1,
"book_length": 0,
"img": "book1.png",
"summary": "Summary 1",
"rate_avg": "2.75",
"created_at": "2022-03-04T18:46:32.000000Z",
"updated_at": "2022-03-04T18:52:28.000000Z",
}
in your query
Book::where('id',$bid)->with('author')->first()
you are getting the book that has that id and you are eager loading the author relation, so in order to get the author you have to access the author field:
Book::where('id',$bid)->with('author')->first()->author
As I said I can this with collection like this:
$b=Book::where('id',$bid)->with('author')->first();
$book=collect([
'id'=>$b->id,
'name'=>$b->name,
'author'=>$b->author,
'category_id'=>$b->category_id,
'level_id'=>$b->level_id,
'book_language_id'=>$b->book_language_id,
'book_length'=>$b->book_length,
'summary'=>$b->summary,
'rate_avg'=>$b->rate_avg,
]);
But this method seems unnecessary
In your example the only difference between the output and what you want is "author_id": 3, as been deleted.
So if you don't want a column or rename a column, you need to use ->select and take all the field you want. And you can also rename with something like that
-> select(DB::raw('author_id as auhtor'), 'books.*')

Laravel filter with where statement

I have this code in my controller and the output is this
$list = ShopDepartment::with('shop','grocery', 'dailylist')->get();
return $list;
Output example for the first item is this
{
"id": 2,
"shop_id": 1,
"name": "Grønt",
"order": "2",
"created_at": "2020-10-12 14:03:57",
"updated_at": "2020-10-12 14:03:57",
"shop": {
"id": 1,
"name": "Netto",
"address": null,
"type": null,
"created_at": "2020-10-12 14:04:35",
"updated_at": "2020-10-12 14:04:35"
},
"grocery": [],
"dailylist": []
},
But if I want to filter the output for shop.id it wont allow me. Any idea how to do this? I assume I can not filter it like that...
$list = ShopDepartment::with('shop','grocery', 'dailylist')->where('shop.id', 1)->get();
return $list;
You could try something like this:
$list = ShopDepartment::with(['shop' => function($query) {
$query->where('id', 1);
}, 'grocery', 'dialylist'])->get();

Laravel add variable for nested collections

I want to add variable to each object of collection inside collection. Here JSON response like this:
{
"id": 16,
"survey_id": "8",
"title": "How are you?",
"created_at": "2020-02-06 04:21:44",
"updated_at": "2020-02-06 04:21:44",
"answers": [
Here I want to add variable to each answer
{
"id": 52,
"question_id": "16",
"text": "VERY GOOD",
"created_at": "2020-02-06 04:21:44",
"updated_at": "2020-02-06 04:21:44",
"reports_count": "4",
"responded": 2
},
{
"id": 53,
"question_id": "16",
"text": "OK",
"created_at": "2020-02-06 04:21:44",
"updated_at": "2020-02-06 04:21:44",
"reports_count": "4",
"responded": 2
},
{
"id": 54,
"question_id": "16",
"text": "BAD",
"created_at": "2020-02-06 04:21:44",
"updated_at": "2020-02-06 04:21:44",
"reports_count": "2",
"responded": 2
}
]
},
Overall, I want to add for every answers variable like $respond = $answer->reports()->count(); Help PLease!!
You could do something like this, if you want to calculate it in the collection directly.
$yourCollection->transform(function($collectionItem) {
$collectionItem['responded'] = $collectionItem->answers->count();
return $collectionItem;
});
But you could do this also on the sql side. I think it should be also the better way ;)
I would fetch the answers from the database before assigning that array to a new question-object-property.
public function get() {
// fetch parent question
$question = Question::where('title', $title)->get();
// fetch answers
$answers = Answers::where('parent_id', $question->id)->get();
// create property called "answers"
$question->answers = $answers;
return response()->json($question);
}

How to merge two collections with a specific condition in laravel?

I have Two collections competences and coCompetences those collections look like :
competence :
...
{
"id": 6,
"category_id": 17,
"user_id": 1,
"objective_level": 4,
"current_level": 4,
"target_date": "2021-11-28",
"obtained_date": "2022-10-14",
"comment": "",
"created_at": "2020-01-08 10:06:28",
"updated_at": "2020-01-08 10:06:28",
"name": null,
"competenceName": "Hierarchy Building & BOM (Bill of Material)",
"category": {
"id": 17,
"competence": "Hierarchy Building & BOM (Bill of Material)",
"created_at": "2020-01-08 09:53:55",
"updated_at": "2020-01-08 09:53:55",
"wheel_id": 10
}
},
{
...
coCompetences :
{
"category": {
"id": 12,
"competence": "Criticality Analysis",
"created_at": "2020-01-08 09:53:55",
"updated_at": "2020-01-08 09:53:55",
"wheel_id": 10
},
"user_id": 1,
"competenceName": "Criticality Analysis",
"category_id": 12,
"objective_level": 0,
"current_level": 0,
"target_date": "2020-01-14",
"obtained_date": "2020-01-14",
"comment": ""
},
I would like to push only coCompetences elements into competences where coCompetences.category_id are not exist in competences.category_id
in another way : add all coCompetences elements to competences except those where coCompetences.category_id already exists in coCompetences.
I don't want to write code instead of you, algorithm will be enough, I hope.
simplest way
Take array Ids from first array, for example by pluck()
Filter second and return items that don't exist in first
push filtered data to first

Paginate on grouped queries

I'm writing a system to follow cash flow. The users register transactions they made:
(transactions index screenshot)
but I need to get these transactions separated by date. I tried using an Request to index, but it doesn't looked the best pratice (it worked, however). Now I'm trying to do another aproach: retrieve all transactions and paginate them by date. Is it possible?
ps: maybe grouping by months helps? like:
$transactions = Transaction::all()->groupBy(function($transaction) {
return Carbon::parse($transaction->date)->format('m-Y');
});
this returns:
{
"03-2019": [
{
"id": 1,
"title": "Teste 1",
"date": "2019-03",
"user_id": 1,
"description": "Primeiro teste, com entrada de 1500 reais.",
"value": "1500.00",
"flow": 1,
"created_at": "2019-03-24 05:39:45",
"updated_at": "2019-03-24 05:39:45"
},
{
"id": 2,
"title": "Teste 2",
"date": "2019-03",
"user_id": 1,
"description": "Segundo teste, com saída de 500 reais.",
"value": "500.00",
"flow": 0,
"created_at": "2019-03-24 05:39:45",
"updated_at": "2019-03-24 05:39:45"
}
]
}
ps²: yeah, front-end is in brazilian portuguese and english isn't my native language.. :)
Try this out
<?php
use Illuminate\Pagination\LengthAwarePaginator;
$transactions = Transaction::all()->groupBy(function($transaction) {
return Carbon::parse($transaction->date)->format('m-Y');
});
//new LengthAwarePaginator($data,$countOfData,$perPage,$currentPage);
$transactions=new LengthAwarePaginator($transactions->forPage($currentPage,$perPage),$transactions->count(),$currentPage);
Hope it helps...

Resources