Backpack for Laravel charts, append sum to chart - laravel

As I'm trying to implement charts into Backpack for Laravel, I been stuck for a few hours on this problem. The following script gets the number of users created for each day and appends them to an array that is then shown on the charts.
for ($days_backwards = 7; $days_backwards >= 0; $days_backwards--) {
// Could also be an array_push if using an array rather than a collection.
$users = Users::whereDate('created_at', today()->subDays($days_backwards))->count();
$user[] = $users;
}
Every iteration of the loop adds a number to the array (or is it a collection??) so something like [2,5,10,9,...].
I would rather like to get the total amount of users that ever registered, incrementally for each day, so that the result would be someting like [2,7,17,26,...].
I figured I could add each iteration with array_sum() but it's not working. Is it an array anyways? Is there a way to append to this list the sum to its previous?

Well I kind of figured out!
$sum = 0;
for ($days_backwards = 7; $days_backwards >= 0; $days_backwards--) {
$users = Users::whereDate('created_at', today()->subDays($days_backwards))->count();
$sum = $sum + $users;
$user[] = $sum;
}
It works!

Related

Google Spreadsheet Loop & IF statement: Loop through co-worker list and add them to a rotation schedule

EDIT - SOLVED
I have to make a rotation schedule for coworkers for the next year. Some coworkers have standard days off and I do not want to schedule them on those days.
This is the manual outcome I would like to get.
Example: Consultant A does not work on mondays, so I do not want Consultant A to be added to the schedule on a monday.
I then want consultant B to be added to the schedule as a fill-up. Consultant A would be next in line on a tuesday etc. Next would be consultant C but consultant C does not work on wednesdays. Therefore, we need to take consultant D for wednesday and consultant C on a thursday, and so on. When we are at the last consultant of the F column, it needs to start again at consultant A.
I have tried all kinds of formulas, like if statements and arrayformula. But there is no way that I know of to loop through the F column just with formulas.
I am not sure if this is at all clear what I want to achieve here, I am stuck 😄
I am using additionally an add-on to send the schedule to everyone's agenda, thats also the reason why i'd love to automate this, because it would help me SO much.
I did try myself on some coding, but I am no coder and I am not sure if it would be helpful at all to share my failure 😄 But this is what I've tried so far:
function Loop() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var EndRow = ss.getLastRow();
for (var i = 2; i <= EndRow; i++) {
var Day = ss.getRange(i,2).getValue();
var Consultants = ss.getRange(i,6).getValue();
var Off = ss.getRange(i,7).getValue ();
var Count = ss.getRange(i,8).getValue();
if(Day == Off){
ss.getRange(i, 3).setValue(Consultants)
}else{
ss.getRange(i, 3).setValue(Consultants)
}
}
}
EDIT:
I found a way without using apps scripts, costs me some more work manually and first tried it with a shorter team list.
The highlighted yellow cells are the cells in which the day off was identical to the work-day cell. So they got switched.
I did have to copy paste my input list of consultants but if this is the only manual way, its fine :)
Try this:
Code:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Sheet1");
var dayCol = sh.getRange("B2:B343").getValues().flat(); //get day column values and convert it to 1d array
var dayOffCol = sh.getRange("G2:G9").getValues().flat(); //get day off values and convert it to 1d array
var dayOffColCopy; //initialize copy
var consCol = sh.getRange("F2:F9").getValues().flat(); //get consultants values or column F
var consColCopy; //initialize copy
var tempArray = []; //storage of final value for column C
for(var i = 0; i < dayCol.length; i++){ //loop through dayCol values
var ctr = (i % consCol.length); //used modulo as counter. the value will return to 0 if the value of i is divisible to the length of consCol or in example 8
//The if statement below will help up reset the value of
//consColCopy and dayOffColCopy once the values are emptied because of the splice()
if(ctr == 0){
consColCopy = consCol.slice();
dayOffColCopy = dayOffCol.slice();
}
//the loop below will get the first non-matching values of dayCol and dayOffColCopy,
//the first non-matching values will be removed to the copy variables using splice()
//and insert it to tempArray using push()
for(var j = 0; j < dayOffColCopy.length; j++){ //loop through dayOffColCopy values
if(dayCol[i] != dayOffColCopy[j]){
tempArray.push(consColCopy.splice(j, 1));
dayOffColCopy.splice(j, 1);
break; //exit loop
}
}
}
sh.getRange(2, 3, tempArray.length, 1).setValues(tempArray); //set the values of temp array to column C
}
Example Data & Output:
Note: Make sure to use the cell that has data in your range and change the sheet name. I also added comments in my code to explain the process.
References:
Array.prototype.push()
Array.prototype.slice()
Array.prototype.splice()
Class Range

foreach with get() return only one record laravel?

i want to sum profit by activating multiple plans. I am using get() with foreach but it returns only last row data. not all rows data. its strange while on other queries it returns all rows data.
for example, I have 2 deposits one 25$ and 2nd 35$ its returns 35$ data only.
i tried with
$deposits = Deposit::get();
but it is not working I went to increase rows to 12 but still, it returns data of 12th row only
$deposits = Deposit::where('account_id', $account->id)->where('status',1)->get();
foreach($deposits as $pn) {
$plans = package::where('id',$pn->plan)->first();
$percent = $plans->min_amount * $plans->percent/100;
}
After discussing in chat, the real problem is adding up the percentages during looping :
$percent = 0;
foreach ($deposited as $de) {
$pack = Package::Where('id', $de->plan)->first();
$log = Deposit::Where('id', $de->id)->first();
$percent = $percent + ($log->amount * $pack->percent / 100);
}

Laravel get the position/rank of a row in collection

I have a leaderboards and leaderboard_scores table.
leaderboard_scores has columns: id, leaderboard_id, player_id, score.
In Leaderboard model, I defined a hasMany relationship with LeaderboardScore:
public function scores()
{
return $this->hasMany('App\LeaderboardScore')->orderBy('score', 'desc');
}
Now I want to get the ranking of a player in a particular leaderboard.
So in controller, I do a loop to find the position given a player_id:
$score = $leaderboard->scores;
$scoreCount = $scores->count();
$myScore = $scores->where('player_id', $request->query('player_id'));
if ($myScore) { // If got my score
$myRank = 1;
for ($i = 0; $i < $scoreCount; $i++) {
if ($scores[$i]->player_id == $request->query('player_id')) {
$myRank = $i + 1;
break;
}
}
// Output or do something with $myRank
}
It works fine, but I am worried about the performance, when I have hundred thousand of players and they constantly getting their ranking. The for loop seems not a good option.
Should I use raw database query? Or any better idea?
Here some ideas
Instead of calculating ranks each time you get request, then loop through all data. you can just store players rank either in database or cache. You only need to calculate them when new player added/deleted or score changed.
Check For Caching:
https://laravel.com/docs/5.4/redis
if you still want to calculate it everytime you can use mysql rank function which is more optimized than a primitive loop
Mysql Rank : http://www.folkstalk.com/2013/03/grouped-rank-function-mysql-sql-query.html

AJAX GET REQUEST WITH MULTIPLE PARAMETERS, ONE URL, RESULTS PUSHED INTO ARRAY

I am using the Indeed job search API which only shows 25 results per GET request.
I need to make 4 GET requests to receive 100 search results, incrementing the &start= number by 25 in the query URL every time.
I can recieve the first set of 25 results just fine, but I want to add a loop that increments the search results by 25, 4 times. The problem is I don't know how to add a callback function that waits for the loop to run 4 times and then pushes ALL 100 results into a single array, and THEN returns the results.
Can anyone help? This is my non-working code.
I am using NODE, and AXIOS for the GET requests.
var axios = require("axios");
var emptyArray = [];
var num = 0;
function runQuery(term){
for(var x=0; x<=3; x++){
var URL = "https://api.indeed.com/ads/apisearch?
publisher=4548xxxxxxxxxxxx&v=2&format=json&q=&l=" + term + "&radius=25&start=" + num + "
&limit=25&latlong=1&co=us&userip=1.2.3.4&useragent=GoogleChrome&v=2"
return axios.get(URL).then(function(response) {
for(var y=0; y<=response.data.results.length-1; y++){
emptyArray.push(response.data.results[y]);
}
return emptyArray;
}); //End axios.get
num = num+25;
}//End For Loop
} // End runQuery
runQuery("New York");
I might be wrong, but I think u just don't need the second for loop inside your callback, because your first loop already do the magic. It will trigger .get four times with 4 different callbacks. And use applyfunction to add response array to the existing one. Try to do it like this:
return axios.get(URL).then(function(response) {
emptyArray.push.apply(emptyArray, response.data.results);
}); //End axios.get
num = num+25;

Skip and take all?

In eloquent, how can I skip 10 rows and then get the rest of the table?
User::skip(10)->all();
The above does not work, but it gives you an idea what I am looking for.
Try this:
$count = User::count();
$skip = 10;
User::skip($skip)->take($count - $skip)->get();
With one query:
User::skip($skip)->take(18446744073709551615)->get();
It's ugly, but it's an example from official MySQL manual:
To retrieve all rows from a certain offset up to the end of the result
set, you can use some large number for the second parameter. This
statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
try something like this it work for sure..
$temp = User::count();
$count = $temp - 10;
$data = User::take($count)->skip(10)->get();
Laravel 5 returns Eloquent result as Collection.
So you can use collenction function slice();
$users = User::get();
$slicedUsers = $users->slice(10);

Resources