I am trying to get the total amount collected in a month, let's say January.
I am able to retrieve all the created_at fields which were created in the month of January in the $main_data_January variable. The $main_data_January variable contains this type of results.
As you can see, each item has a field called amount.
Problem
I want to retrieve the value of amount field from each item and sum them up. As I'm doing it in the total_earnings_janunary, but this is where I am facing the problem.
By adding both the amounts, the expected result should be 13000, but
the result is 8000. It is only getting only the first value of amount after being in a loop.
$customers = Tag::all();
$total_earnings_janunary = 0;
$query_date = '2017-01-04';
$start_date_janunary = date('Y-01-01', strtotime($query_date));
$end_date_janunary = date('Y-m-t', strtotime($query_date));
foreach ($customers as $customer) {
if (Auth::User()->gym_code == $customer->gym_code ) {
$main_data_janunarys = DB::table('tags')->whereBetween('created_at', [$start_date_janunary,$end_date_janunary])->get();
}
}
for ($i=0; $i <= count($main_data_janunarys); $i++) {
$total_earnings_janunary = $total_earnings_janunary + $main_data_janunarys[$i]->amount;
dd($total_earnings_janunary);
}
Few things to note:
You're querying the Tag model and storing it in $customers. Resulting entities are not customers. Make sure that's intended.
In the first foreach loop, you are overwriting previous value of the $main_data_janunarys over and over. Use break if that's intended.
In the for loop, you are dding early. Move it outside the loop and you'll see your intended results. In the loop exit condition you should be using < instead of <= as you're starting from zero.
To sum up the collection you could just use Collection::sum() method, like: $main_data_janunarys->sum('amount');.
Try this:
$customers = Tag::all();
$total_earnings_janunary = 0;
$query_date = '2017-01-04';
$start_date_janunary = date('Y-01-01', strtotime($query_date));
$end_date_janunary = date('Y-m-t', strtotime($query_date));
foreach ($customers as $customer)
{
if( Auth::User()->gym_code == $customer->gym_code ) {
$main_data_janunarys = DB::table('tags')->whereBetween('created_at', [$start_date_janunary,$end_date_janunary])->get();
}
}
$total_earnings_january = $main_data_januarys->sum('amount');
You can read further about Laravel's Collection here
Related
I am trying to create a number of arrays to add to a larger array which I will then index two dimensionally (for example my_array[i][j]).
I believe I am having some type of pointing issue... I am iterating through a loop.... at the top of each iteration I instantiate a new array with the same name. When I try and view the output each item in the array appears blank.
Is there a better way for me to instantiate the "temp" arrays to fill the larger (outer) array? Really appreciate any and all help, this community has helped me through so many questions :D
$main_array = array();
for($i = 0; $i < $member_count; $i++)
{
$temp_array = array();
//preform SQL query here
$sql_get_member_transactions = 'some SQL query to go to my DB';
foreach($sql_get_member_transactions as $row)
{
//cannot get array to update here
array_push($temp_array, $row['amount']);
}
array_push($main_array, $temp_array);
}
#***FULL CODE BELOW***
$club_transactions = array();
for($i = 0; $i < $member_count; $i++)
{
#create an array for each member in the club,
#add each memeber's array to a larger array once filled with deposit amounts
#here check if member had a deposit (later we will check ALL transaction types...)
#if no deposit on that date add a zero to their array
$temp_member_transactions = array();
$temp_member = my_members[$i];
$sql_member_transactions = "SELECT * FROM Transactions WHERE Date >= '$first_t_date' AND Date <= '$last_t_date' AND RelatedClubID = 'THH'";
$sql_get_member_transactions = mysqli_query($conn, $sql_member_transactions);
//here we will get all transactions that lie within the
//event-transaction-date-window... in otherwords, the date window
//in the year where members transactions occured
foreach($sql_get_member_transactions as $row)
{
//we only want to include the transaction amount
//in the member-specific array if it belongs to that member
//otherwise see "else"
if($row['T_Owner'] == $temp_member)
{
$z = $row['T_Amount'];
}
else
{
//set to 0 so that we still account for the transaction date
$z = 0;
}
array_push($temp_member_transactions, $z);
}
array_push($club_transactions, $temp_member_transactions );
My Code:
$filter = Products::select(DB::raw('SUM(price) as `total_price`')
DB::raw('SUM(count) as `total_count`')
DB::raw("DATE_FORMAT(date, '%m/%Y') new_date"),
DB::raw('YEAR(date) year, MONTH(date) month'))
->groupBy('year', 'month')
->get();
$result = [];
$total_price = 0;
$total_count = 0;
$new_date = null;
foreach($filter as $f){
$new_date = $f->new_date;
$total_price = $f->total_price;
$total_count = $f->total_count;
}
*note : please use dd($f) ,
it will display total price, total count, and new date but it always the latest ones that shown
example:
if i input price and count at 02-08-2018 first
i input price and count at 02-08-2020 second,
i input price and count at 02-08-2016 third,
it will show the latest date which is all the data in 02-08-2020
what i want is, it will show according to the latest submit or input, which we can get by the latest request in form,
if we look at the example, the expected result should be all the data at 02-08-2016 .
Can anyone help me please????
$st = $this->db->prepare("SELECT * FROM invoices WHERE group_id=?");
$st->execute(array($id));
if($st->rowCount() >= 1){
foreach ($st as $row) {
$counter = $row["paymentAmount"];
$start = 1;
for($start; $start < $st->rowCount(); $start++) {
$counter = $counter + $row["paymentAmount"];
}
}
It actually print out $row["paymentAmount"] + $row["paymentAmount"] and so on, depending on how many $row["paymentAmount"] there is. But the problem is that the last output from $row["paymentAmount"] is 2500.
There is:
10000
10000
2500
And the result is: 7500
I want it to be: 22500
And if the last result is 3000 it shall be 23000. So what I simply need is this code to take every row from the database, just not the latest one.
Edit: I want it outside of the SQL query
You don't need PHP logic for something like this. The functionality is built right into SQL.
SELECT SUM(paymentAmount) FROM invoices WHERE group_id=?
You should let your database handle the sum unless you have a legitimate reason why it needs to be handled in PHP. The database is more efficient with this type of operation and you avoid a loop in PHP.
SELECT SUM(paymentAmount) AS TotalPaymentAmount FROM invoices WHERE group_id = ?
You can then change your PHP to return just one row:
$row = $st->fetch();
echo $row["TotalPaymentAmount"];
If you need to do this calculation outside of SQL, just change your loop:
if($st->rowCount() >= 1){
//init the counter to 0 before you loop through your rows
$counter = 0;
//the foreach will iterate over your result set and add the paymentAmount to $counter.
foreach ($st as $row) {
$counter += $row["paymentAmount"];
}
//echo results outside of the loop
echo $counter;
}
If you need to code this outside SQL on purpose (e.g. because you need to do further processing for each row), then I'd code this as follows:
if ($st->rowCount() >= 1) {
$counter = 0;
foreach ($st as $row) {
$counter += $row["paymentAmount"];
}
}
I've got a small problem. I'm working on a little package/product-list.
If you're watching a Package, my website should show you which products are in there.
If a product is more than one time in it, the array should be deleted and the value of the leftover array should be + 1 (each deleted array).
So here's my code:
// $products_in_package has all products in it
// First of all, the products come from a db and don't have a count
// So i first give them a count of 1
foreach ($products_in_package as $product => $value) {
$products_in_package[$product]['count'] = intval(1);
}
foreach ($products_in_package as $product) {
$id_to_find = intval($product['ID']);
$product_count = intval($product['count']);
$found_id = 0;
// Now I try to find any ident products
// If found and over 1 time (beacouse he finds the first too of course)
// Then delete this array and count up the products count
for ($i=0; $i <= count($products_in_package); $i++) {
if(intval($products_in_package[$i]['ID']) === $id_to_find){
$found_id++;
if($found_id > 1){
$product_count = $product_count + 1;
$product['count'] = $product_count;
unset($products_in_package[$i]);
array_merge($products_in_package);
while($i > $products_in_package){
$i = 0;
}
}
}
}
}
What I'm getting is the correct multidimensional array but the count is still 1.
What's wrong with the code?
Everytime I try to log the code i'm getting the right integer. (No, I already tried to delete the chache)
But if I log the array out of the loops, I get always the count of 1.
$product is a copy of the array element, so when you do $product['count'] = $product_count you're assigning to a copy, not the original array.
You can fix this by using a reference in the foreach:
foreach ($products_in_package as &$product) {
I have a form that has 7 different items. The user will be able to input quantity (unlimited) and the price will be set for each item (let's say for example, item 1 is $18, and item 2 is $20, etc.). What I have done with another form that's almost identical is this:
if(!empty($_POST[qty_item_1])) {
$total_1 = ($_POST[qty_item_1] * 18);
} else {
$total_1 = "0";
}
if(!empty($_POST[qty_item_2])) {
$total_2 = ($_POST[qty_item_2] * 20);
} else {
$total_2 = "0";
}
I would have a code block like those for each item. It seems to work fine but I feel like this is probably the hard way to do it but I'm having trouble figuring out what else I might do. Any suggestions?
Given your field names, you could do something like:
$totals = array();
for ($i = 1; $i <= 7; $i++) {
$total[$i] = isset($_POST["qty_item_{$i}"]) ? intval($_POST["qty_item_{$i}"]) : 0;
}
The other option is to simply name your fields qty_item[]. When PHP parses the submitted data, it'll convert all those qty_item fields into an array for you. You'd still need to post-process to make sure that they contain valid numbers and whatnot, thoguh.