How to use groupBy Month and Sum in laravel MongoDB - laravel

Query to get monthly orders (total orders per month(count) or total sales per month(sum)):
Tried this query, but it is not working. Also tried with other results from StackOverflow, but I didn't understand how it is done with MongoDB query. This is the link to that question : select-sum-column-and-group-by-with-mongodb-and-laravel
$monthly_orders = Order::select(
DB::raw('sum(total_amount) as sum'),
DB::raw('YEAR(created_at) year, MONTH(created_at) month'),
)
->groupBy('month')
->get();
When I try to get total amount by using group by customer ID , it is returning sum as null
$monthly_orders = Order::selectRaw('sum(total_amount) as sum, customer_id')
->groupBy('customer_id')
->pluck('sum', 'customer_id');
Result :
Illuminate\Support\Collection {#2123 ▼
#items: array:4 [▼
"6098e5ff5977a25ee96a2a42" => null
"60dbf87f7d8ffb7cdb2233d2" => null
"605af409195d8e59e34893f2" => null
"60ddae4a66fb69678e45f056" => null
]
}

Try using raw and aggregate
$monthly_orders = Order::raw(function ($collection) {
return $collection->aggregate([
[
'$group' => [
"_id" => '$customer_id',
'customer_id' => ['$first' => '$customer_id'],
'sum' => ['$sum' => '$total_amount']
]
],
]);
});
you can use pluck
$monthly_orders->pluck('sum','customer_id')
Group by month
$monthly_orders = Order::raw(function ($collection) {
return $collection->aggregate([
[
'$group' => [
"_id" => ['$month'=>'$created_at'],
'customer_id' => ['$first' => '$customer_id'],
'sum' => ['$sum' => '$total_amount']
]
],
]);
});

Related

Larvel Query Builder group By with pluck

id
agent_id
currency
1
A0001
IDR
2
A0002
MYR
3
A0001
THB
example currently have a dataset as above,
is it have any way to using only 1 query builder to get the outcome like below
Output:
[
"agent_id" => "A0001",
"currency" => [
"IDR",
"THB",
],
],
[
"agent_id" => "A0002"
"currency" => ["MYR"]
]
Basically likes try to pluck the currency under same agent
Appreciate for all the suggestion.
Found a solution for this problem
$output = $output
->get()
->groupby('agent_id')
->map(function($rows){
return [
"agent_id" => $rows[0]['agent_id'],
"currency" => $rows->pluck('currency'),
];
});

I want to sort the related values that are obtained by contain in pagination (CakePHP4)

Get the value of contain for the Slugs associated with the Posts model.
I want to sort them in order of the ID of the retrieved Slugs table.
in PostsController
/**
* Index method
*
* #return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$this->paginate = [
'limit' => 10,
'contain' => ['Slugs'],
'order' => [
'Slugs.id' => 'desc',
],
];
$posts = $this->paginate($this->Posts);
$this->set(compact('posts'));
}
The retrieved values will be displayed in order of decreasing ID (asc).
ID in descending order.
Check the contents of the $posts value in dd($posts).
0 => App\Model\Entity\Posts {#163 ▼
#_accessible: array:6 [▶]
#_fields: array:6 [▶]
// ....
id: 1
title: "CakePHP"
user_id: 1
created: Cake\I18n\FrozenTime #1613560300 {#164 ▶}
modified: Cake\I18n\FrozenTime #1613560300 {#195 ▶}
users: array:2 [▼
0 => App\Model\Entity\Slug {#213 ▼
// ...
id: 1
name: "PHP7.2"
[new]: false
// ...
}
1 => App\Model\Entity\Slug {#224 ▼
id: 2
name: "CakePHP4"
// ...
I have tried the following
'order' => [
'Posts.Slugs.id' => 'desc',
],
or
$posts = $this->paginate($this->Posts->find()->order(['Slugs.id']);
How can I get the best results?
So a Post has many Slugs, and when you load posts in the pagination (sorted by some field in the post), you want the slugs in those posts to be ordered by id? You should be able to do this with the queryBuilder parameter in the containment:
$this->paginate = [
'limit' => 10,
'contain' => [
'Slugs' => [
'queryBuilder' => function (Query $q) {
return $q->order(['Slugs.id']);
}
],
],
];

get a data from an array

get a data from an array ..code for getting cart
public function show()
{
$data = $this->cartService->getCart(auth()->user()->id);
dd($data);
}
Response
array:2 [
"cart" => array:9 [
"id" => 244
"user_id" => 53
"total_mrp" => "56000.00"
"promo" => "HELLO"
"discount" => "30.00"
"meta" => {#1575
+"sub_total": 56000
}
]
"cart_items" => array:1 [
]
]
]
]
HOW CAN I GET PROMO IN A Variabel???
i tried
return $data->promo;
but error
You can use collect(). You can read about this function from laravel doc
$data = $this->cartService->getCart(auth()->user()->id);
$cart = collect($data['cart']??[]);
dd($cart->get('promo'));

Apply reduce method for all properties of an object

I have an object in Laravel that represent a monthly report.
0 => array:20 [▼
"id" => 43
"operation_id" => 1
"meter_id" => 3
"period" => "monthly"
"total_conso" => "103.42"
"total_autoconso" => "59.47"
"total_grid" => "43.95"
"bill" => "31.95"
"grid_fee" => "26.97"
"solar_turpe_tax_fee" => "4.99"
"savings" => "4.41"
"total_prod" => null
"total_surplus" => null
"autoconso_rate" => "57.5"
"autoprod_rate" => null
"surplus_rate" => null
"date" => "2019-08-24T00:00:00.000000Z"
"created_at" => "2019-08-24T00:00:00.000000Z"
"updated_at" => "2020-10-01T15:03:38.000000Z"
I have a array with 12 objects of these, one per month.
I am calculating the yearly report values, and I have to sum all 12 month for each field.
I can do it with reduce field by field with:
$totalConso = $reports->reduce(function ($sum, $report) {
return $sum + $report->total_conso;
}, 0);
What I am looking for is a way to do it for all fields. Is it possible ? It would allow me not to duplicate 10 times the same reduce function
Thanks !
You could do something like this:
[$totalConso, $totalAutoConso] = collect(['total_conso', 'total_autoconso'])->map(fn ($property) => $reports->sum($property));
If you would prefer an array with each total:
$totals = collect(['total_conso', 'total_autoconso'])->mapWithKeys(fn ($property) => [$property => $reports->sum($property)]);
This would give you a collection with all the totals.
If you don't like hardcoding the list of total_* attributes, you can get them dynamically from the list of fillable attributes of your model (this assumes you use the fillable property):
$totals = collect(Report::make()->fillable)
->filter(fn ($property) => strpos($property, 'total_') === 0)
->mapWithKeys(fn ($property) => [$property => $reports->sum($property)]);
Demo: https://laravelplayground.com/#/snippets/ec3c662f-0ab9-4de8-8422-7bed2f054677
Use the collect helper and sum method:
$total = collect($reports)->sum('total_conso');

select data based on the array

I have an array from query like below:
array:84 [
0 => array:2 [
"comp" => "50007148"
"cus" => "F0401"
]
1 => array:2 [
"comp" => "50007148"
"cus" => "J0050"
]
2 => array:2 [
"comp" => "50007148"
"cus" => "L"
]
3 => array:2 [
"comp" => "50007148"
"cus" => "LT"
]
4 => array:2 [
"comp" => "50007148"
"cus" => "RP"
]
Now I need to write a query where comp, cus in above query.
$rslt = Stdetl::whereIn('comp, cus', $categories)
->where(YEAR(docdate), '=', 2019)
->get(SUM(number))->toArray();
But this query is not working. I am getting error as follows:
(1/1) FatalErrorException
Call to undefined function App\Http\Controllers\YEAR()
But this is not the only mistake in that query .
YEAR() is a mysql function, you should use whereRaw() to query this. Like this:
->whereRaw('YEAR(docdate) = 2019')
Update:
For your whereIn() part, you have to make two queries, one for each column. So you will have to get the correct values from the array. This can be done using array_map.
For example:
->whereIn('comp', array_map(function($cat) { return $cat['comp']; }, $categories))
->whereIn('cus', array_map(function($cat) { return $cat['cus']; }, $categories))
You can't use whereIn like that, use this way
$rslt=Stdetl::whereIn('comp', $categories)
->whereIn('cus', $categories)
->where(date('Y', strtotime(docdate)), '=', 2019)
->get(SUM(number))->toArray();;

Resources