Laravel get rows from table using timestamp column - php

In my table, I have 2 columns:
1-count_of_h 2- updated_at
Now I want select rows which is past the updated_at, count_of_h hours.
A code like this:
$rows = Model::where('updated_at', '<', Carbon::now()->subHours($row->count_of_h))->get();
But I don't know how can I do it.

My code is kinda dirty ( but it works )
$arrayOfData = [];
Model::chunk(100, function($model) {
foreach($model as $m) {
if($m->updated_at < Carbon::now()->subHours($m->count_of_h)) {
$arrayOfData[] = $m;
}
}
});
First is make an array. After that, it will take every 100 rows then check if its past count_of_h hours

Related

match the array from DB column with another DB table column in laravel

I'm getting data through the 2 table in form of array (like address) and one to find particular pin code in another table here is the 2 model that i'm using to find and match the result and perform the tax function eg. if one table have the array a.b,c,d the second table have the value to find the value store in it eg. if a = 1 if b=2 like that here is my code idea trying to implement but no success
try
{
$toltax = toltax::wheresource('LIKE','%'.$s_address.'%')->get();
$tsource = $toltax->source;
$tdestination = $toltax->destination;
if(!empty($toltax = toltax::where($s_address, 'LIKE' ,"%$tsource%")
->where($d_address,'LIKE',"%$tdestination%")
->get('tax')
)
){
Log::info("toll tax".$toltax->tax);
$Tax = $Tax + $toltax->tax;
}
}catch(ModelNotFoundException $e) {
return false;
}
try this i hope help you
$tax = DB::table('toltax as latest')
->whereSource('LIKE','%'.$s_address.'%')
->whereNotExists(function ($query) {
$query->select(DB::raw(1))
->from('toltax')
->whereRaw('source LIKE latest.source')
->whereRaw('destination LIKE latest.destination');
})
->get(['tax']);

Total Invoices - Receipts not adding up

I have the next issue - I have a table invoices and a table with receipts. An invoice is created by an agent and I want to get the sold for each agent but the numbers are wrong.
Here is what I've tried:
$agents = Agent::get();
$invoices_receipts_agent = array();
foreach ($agents as $agent) {
$payment_invoice = 0;
$payment_recepit = 0;
$id_agent = $agent->id_agent;
$invoices = Invoice::whereAgent_id($id_agent)->get();
foreach ($invoices as $invoice) {
$payment_invoice = $payment_invoice + $invoice->total_pay;
$recepits = Recepit::whereInvoice_id($invoice->id_invoice)->get();
if (count($recepits) > 0) {
foreach ($recepits as $recepit) {
$payment_recepit = $payment_recepit + $recepit->amount_payd;
}
}
}
$total = $payment_invoice - $payment_recepit;
$total_agents = ['name' => $agent->name, 'total' => $total];
array_push($invoices_receipts_agent, $total_agents);
}
I made a test and created two invoices for the agent with ID 5
First invoice: 10
Second invoice : 20
Total invoices: 30
Then I did a recepit for the second invoice and found the expected total:
Total: 10 + 20 - 20 = 10 (correct total)
And that's great, but I have an agent with 3600 invoices and something is wrong the total. The total (total = invoices - recepits) is too big, but I can't figure out why.
Extra detail: the fields for the numbers are float.
First of all, you have an easier way to handle this issue using Eloquent Relationships.
In this case, can define One-to-Many relationship between Agent and Invoice as:
class Agent {
...
function invoices(){
return $this->hasMany('App-Namespace\Invoice')
}
}
...and define the inverse relationship on Invoice.
Then, you must do same between Invoice and Receipt models, since an Invoice can have one to many receipts.
So, if Agents table primary key is id you could say:
$agent = Agent::find($agent_id)->invoices->get();
...to get an agent invoices; or:
$invoice = Invoice::find($invoice_id)->receipts->get();
...to get all receipts for a specific invoice.
And finally implement your code:
$agents = Agent::all();
$invoices_receipts_agent = array();
foreach ($agents as $agent) {
$payment_invoice = 0;
$invoices = $agent->invoices->get();
foreach ($invoices as $invoice){
$payment_invoice += $invoice->total_pay;
$payment_receipt += $invoice->receipts->sum('amount_paid');
}
$total = $payment_invoice + $payment_receipt;
$invoices_receipts_agent[] = ['name' => $agent->name, 'total' => $total];
}
Note: I have used sum collection function to get sum of values of column amount_paid of a particular receipt. You could do same to get sum of total_pay column of an invoice like:
$total_paid = $agent->invoices()->sum('total_pay');
Can you confirm it this current version of your code?
I see some typos like in:
$recepits = Recepit::whereInvoice_id($invoice->id_invoice)->get();
if (count($receipts) > 0) {
Here we have issues:
Variable is named $recepits, but then called in next line with other name ($receipts).
$receipts should be a collection (result of Eloquent query) not an array. So to get count you have to say: $receipts->count()
If this is your final code, those are definitly error which are affecting your result.

How to increment MySQL field by one if one or more items are checked in form?

I have a page where user can vote which gaming platform (for example) is the best. In MySQL I have a table of these items. I want to update 'count' field and set it to +1 every time when specified item is checked.
After form is submitted I get an array of selected items:
array [
0 => "XBOX"
1 => "PS4"
2 => "PC"
]
Now, I want to check and compare this array with MySQL fields and increase their count values by 1.
I am trying to compare array with MySQL with this, but unsuccessfully.
$value = Input::get('platform'); //this produces presented array
$test = Platform::where('name', 'LIKE', implode(" ", $value))->get();
I think you should use whereIn instead of where
$test = Platform::whereIn('name', $value)->get();
Update:
You can do this by DB::raw():
DB::table('Platforms')
->whereIn('name', $value)
->update([
'count' => DB::raw('count + 1')
]);
I'm not familiar with your query builder, but in SQL you would just do something like this:
UPDATE table_name SET counter=(counter+1) WHERE name IN ('XBOX', 'PS4', PC');
Where table_name is your table name and counter is the name of the field that keeps track of the counts.
This will increment each matched platform by 1.
Now it works. If someone needs code example, here it is. Thank you guys.
public function vote()
{
$value= Input::get('platform');
$test = Platform::whereIn('name', $value)->get();
for ($i = 0; $i < count($test); $i++) {
$test[$i]->count += 1;
$test[$i]->save();
}
}

Sorting a NON-SQL table column in a table containing data from SQL query

Below I have stripped down my code to a simplified version. I am storing SQL SELECT results for:
last name (dlname)
category (category)
date this data was added to database (date_added)
clients name (client)
I have appended an additional field outside the SQL SELECT called 'days_on_list'. This field shows the number of days since the data was added to the database, making the table output 5 columns of user data. ALL 5 COLUMNS ARE TO BE SORTABLE.
I am using server-side JSON and have successfully been able to display this to the table and perform sorting on 4 of the 5 columns. The problem is that I am unable to sort the 'days_on_list' field as the PHP file containing the SQL code only allows me to sort the 4 fields from the select query. Is there a way I can make 'days_on_list' column be sortable in the table? I know I can add this field to the sql table, but I would have to run a scheduled event on the server to update this daily (which I am not comfortable with).
Is there another way to allow for this kind of flexible table sorting?
Sorry about the question title (may be confusing), I was having trouble putting this into a question.
/*SQL CODE ABOVE HERE STORES SELECT RETURNS IN $result*/
$cart = array();
$i = 0; //index the entries
// get variables from sql result.
if ($num_rows > 0) { //if table is populated...
while ($row = mysqli_fetch_assoc($result)) {
//calculate days on list by getting the number of days from
//the 'date_added' to today
$date1 = date_create($row['date_added']);
$today = date_create(date("d-m-Y"));
$interval = date_diff($date1, $today);
$doty = $interval - > format("%a");
$cart[$i] = array(
"dlname" => htmlspecialchars($row['dlname']),
"category" => htmlspecialchars($row['category']),
"date_added" => htmlspecialchars($row['date_added']),
"client" => htmlspecialchars($row['client']),
"days_on_list" => $doty, //date_added to now
);
$i = $i + 1; //add next row
}
//encoding the PHP array
$json_server_pagination_data = array(
"total" => intval($num_rows),
"rows" => $cart, //array data
);
}
echo json_encode($json_server_pagination_data);
Because days_on_list is calculated by simply comparing date_added to the current date, sorting by days_on_list should have exactly the reverse effect as sorting by date_added.
In other words, you don't actually need to sort by days_on_list. If the user selects days_on_list as the sort column, just use ORDER BY date_added (in the opposite direction ASC/DESC).

Laravel Eloquent Array Loop

I have an eloquent query that is returning a 'show', and any 'show_ref's relating to it:
Show::where('show_slug','=',$id)->with('showrefs')->firstOrFail();
This brings back a nested array successfully, as follows:
{
"show_id":2,
"show_name":"ShowNo1",
"show_logo":null,
"show_facebook_url":null,
"show_twitter_url":null,
"show_website_url":null,
"show_slug":"shown1",
"created_at":"2014-09-27 11:57:32",
"updated_at":"2014-09-27 11:57:32",
"showrefs":[
{
"show_ref":1,
"show_id":2,
"show_start_date":"2014-05-16",
"show_end_date":"2014-05-21",
"show_year":2014,
"show_common_name":"Mid May",
"venue_id":null,
"created_at":"2014-09-27 12:17:40",
"updated_at":"2014-09-28 06:26:54"
},
{
"show_ref":2,
"show_id":2,
"show_start_date":"2014-05-23",
"show_end_date":"2014-05-28",
"show_year":2014,
"show_common_name":"Late May",
"venue_id":null,
"created_at":"2014-09-27 12:21:24",
"updated_at":"2014-09-28 06:26:58"
},
{
"show_ref":4,
"show_id":2,
"show_start_date":"2013-02-12",
"show_end_date":"2013-02-13",
"show_year":2013,
"show_common_name":"Early February",
"venue_id":null,
"created_at":"2014-09-28 17:50:02",
"updated_at":"2014-09-28 17:50:02"
},
{
"show_ref":5,
"show_id":2,
"show_start_date":"2013-04-27",
"show_end_date":"2013-04-28",
"show_year":2013,
"show_common_name":"Late April",
"venue_id":null,
"created_at":"2014-09-28 17:50:42",
"updated_at":"2014-09-28 17:50:42"
}
]
}
What I am trying to get from my view is the following format:
ShowNo1 (show name)
2014
list of any shows in 2014
2013
List of any shows in 2013
Is there anyway this is possible from what I have coded so far? or have I gone about this the wrong way?
Thanks.
You have a showrefs function in your Show model somewhere that is defining this relationship. #Armon's answer will work, but will run on the order of O(n * years) where years is the number of years you want to show. Your example only has 2, but could be many more, and you can instead display your data in O(n) time.
You can orderBy in the methods defining relationships.:
// app/models/Show.php
public function showrefs()
{
return $this->hasMany('ShowRef')->orderBy('show_start_date', 'DESC');
}
If the tables you are joining together both contain a column which you want to order by, you may need to qualify the order by by appending the table name, as in:
->orderBy('`show_refs`.`show_start_date`', 'DESC')
After that, its just a matter of keeping track of the current year and noticing when it changes when looping over your data:
$show = Show::where('show_slug','=',$id)->with('showrefs')->firstOrFail();
$currentYear = '';
foreach($show->showrefs as $showref) {
$showRefYear = strtok($showref->show_start_date, '-');
if($currentYear != $showRefYear) {
$currentYear = $showRefYear;
// Output Year heading
}
// Output show details
}
Without knowing anything about Eloquent, you can use a simple function to walk through your nested array and collect your shows for a given year:
function collect_shows_with_year($shows, $year)
{
$result = array();
foreach($shows["showrefs"] as $show_ref)
{
if($show_ref["show_year"] == $year)
{
$result[] = $show_ref;
}
}
return $result;
}
$shows_in_2014 = collect_shows_with_year($shows, 2014);
$shows_in_2013 = collect_shows_with_year($shows, 2013);

Categories