Trying to get property of non-object PHP Laravel - php

I know that this question in the tittle is asked WAYY too much in here, and I went thru most of them but still cant find a solution for my code.
function calculatingWages($project_id){
$start_date = '2017-05-01';
$end_date = '2017-12-31';
$project = Project::find($project_id);
$users = $project->users()->get();
$sumWage=0;
foreach ($users as $user){
$timesheetHours = $user->timesheets()->whereBetween('timesheets.date',[$start_date,$end_date])->sum('hours');
$wages = UserWage::whereBetween('start_date',[ $start_date,$end_date])->whereBetween('end_date',[ $start_date,$end_date])->get();
foreach ($wages as $wage){
$value = $wage->value;
$currency = $wage->currency;
$sumWage = extractMonthsAndCalculate($value,$currency, $timesheetHours, $start_date, $end_date);
}
return $sumWage;
}
}
function extractMonthsAndCalculate($value,$currency, $timesheetHours, $start_date, $end_date){
$start = Carbon::createFromFormat('Y-m-d',$start_date)->month;
$end = Carbon::createFromFormat('Y-m-d',$end_date)->month;
$diffOfMonths = $end - $start;
$sumWage = 0;
for ($i = $start; $i <= $diffOfMonths; $i++) {
$wageYear = Carbon::createFromFormat('Y-m-d',$start_date)->year;
$wageDay = Carbon::createFromDate($wageYear,$i,'01')->lastOfMonth()->toDateString();
$test = convertingALL($value,$currency,$timesheetHours,$wageDay);
}
return $sumWage;
}
function convertingALL($value, $currency, $timesheetHours, $date)
{
$currencyObj = Exchange::where('date',$date)->get()->first();
$currencyDate = $currencyObj->date;
$hourlyWage = 0;
$sumWage = 0;
if($currencyDate == $date) {
$dollar = $currencyObj->dollar_lek;
$euro = $currencyObj->euro_lek;
if ($currency == 'ALL') {
$sumWage = $value;
} elseif ($currency == 'USD') {
$sumWage = ($hourlyWage *$timesheetHours) * $dollar;
} else {
$sumWage = ($hourlyWage *$timesheetHours)* $euro;
}
}else{
$euro = 140;
$dollar = 136.4;
if ($currency == 'ALL') {
$sumWage = $value;
} elseif ($currency == 'USD') {
$sumWage = $value * $dollar;
} else {
$sumWage = $value * $euro;
}
}
return $sumWage;
}
it says that it cant get the property of a non object in line 468
this is line 467-468:
$currencyObj = Exchange::where('date',$date)->get()->first();
$currencyDate = $currencyObj->date;
when I dd $currencyDate it prints the date of it, tried to parse it using carbon but still same thing, where am I messing up?

You need to tell Eloquent that the date field contains a date (even though it seems obvious).
Docs: https://laravel.com/docs/5.4/eloquent-mutators#date-mutators
In your Exchange model you should have
class Exchange extends Model {
protected $dates = [ 'date' ];
On an unrelated note, ->get()->first() will pull every single result back from the database, then chuck all but one of them away. If you just call ->first() then you'll only get one result from the database; same end result but better for performance.

Related

Add missing dates in array

I want to show current week's data. In databse I have some perticular date data I have fill the missing dates and in view page I am showing that by foreach loop because I want to set different values for them. But it is showing mutliple times data because of 2 foreach loop. I want to get result in one array. My code is:
public function cashflowdetails() {
$cashflow = CashModel::orderBy('payment_date','asc') ->get();
$cashflow_array = [];
$cashflowDate_array = [];
$now = Carbon::now();
if (Input::get('from') != '') {
$weekStartDate =Input::get('from') ;
}
else{
$weekStartDate = Carbon::now()->startOfWeek();
}
if (Input::get('to') != '') {
$weekEndDate = Input::get('to');
}
else{
$weekEndDate = Carbon::now()->endOfWeek()->addDay();
}
$period = CarbonPeriod::create($weekStartDate, $weekEndDate);
foreach ($period as $date) {
$dt = new DateTime($date->format("Y-m-d"));
if($dt->format('l')!= 'Sunday' && $dt->format('l')!= 'SUNDAY' && $dt->format('l')!= 'SATURDAY' && $dt->format('l')!= 'Saturday')
{
foreach($cashflow as $cash){
if($date->format("Y-m-d") === $cash->payment_date )
{
$dbData['id'] = $cash->id;
$dbData['payment_date'] = $cash->payment_date;
$d = new DateTime($cash->payment_date);
$dbData['day'] = $d->format('l');
$dbData['opening_balance'] = $cash->opening_balance;
$dbData['other_income'] = $cash->other_income;
$dbData['rent'] = $cash->rent;
$dbData['labour'] = $cash->labour;
$dbData['electricity'] = $cash->electricity;
$dbData['creditors'] = $cash->creditors;
$dbData['insurance'] = $cash->insurance;
$dbData['direct_debits'] = $cash->direct_debits;
$dbData['others'] = $cash->others;
$dbData['total_amount'] = $cash->total_amount;
$dbData['updated_at'] = $cash->updated_at;
$dbData['created_at'] = $cash->created_at;
print_r($cash->payment_date);
$cashflow_array[] = $dbData;
}
else{
$dbData['id'] = null;
$dbData['payment_date'] = $date->format("Y-m-d");
$d = new DateTime($date->format("Y-m-d"));
$dbData['day'] = $d->format('l');
$dbData['labour'] = 0;
$dbData['opening_balance'] = 0;
$dbData['other_income'] = 0;
$dbData['rent'] =0;
$dbData['electricity'] = 0;
$dbData['creditors'] = 0;
$dbData['insurance'] =0;
$dbData['direct_debits'] = 0;
$dbData['others'] = 0;
$dbData['total_amount'] = 0;
$dbData['updated_at'] = '';
$dbData['created_at'] = '';
$cashflowDate_array[] = $dbData;
}
//break;
}
}
}
$cashflow = array_replace($cashflowDate_array, $cashflow_array);
return $cashflow;
}
public function cashflowdetails() {
$cashflow = CashModel::orderBy('payment_date','asc') ->get();
$cashflow_array = [];
$cashflowDate_array = [];
$now = Carbon::now();
if (Input::get('from') != '') {
$weekStartDate =Input::get('from') ;
}
else{
$weekStartDate = Carbon::now()->startOfWeek();
}
if (Input::get('to') != '') {
$weekEndDate = Input::get('to');
}
else{
$weekEndDate = Carbon::now()->endOfWeek()->addDay();
}
$period = CarbonPeriod::create($weekStartDate, $weekEndDate);
foreach ($period as $date)
{
//add a flag to see if the code was executed or not
$isExecuted = false;
$dt = new DateTime($date->format("Y-m-d"));
if($dt->format('l')!= 'Sunday' && $dt->format('l')!= 'SUNDAY' && $dt->format('l')!= 'SATURDAY' && $dt->format('l')!= 'Saturday')
{
foreach($cashflow as $cash){
if( $date->format("Y-m-d") === $cash->payment_date )
{
$dbData['id'] = $cash->id;
$dbData['payment_date'] = $cash->payment_date;
$d = new DateTime($cash->payment_date);
$dbData['day'] = $d->format('l');
$dbData['opening_balance'] = $cash->opening_balance;
$dbData['other_income'] = $cash->other_income;
$dbData['rent'] = $cash->rent;
$dbData['labour'] = $cash->labour;
$dbData['electricity'] = $cash->electricity;
$dbData['creditors'] = $cash->creditors;
$dbData['insurance'] = $cash->insurance;
$dbData['direct_debits'] = $cash->direct_debits;
$dbData['others'] = $cash->others;
$dbData['total_amount'] = $cash->total_amount;
$dbData['updated_at'] = $cash->updated_at;
$dbData['created_at'] = $cash->created_at;
//if executed, assign it true
$isExecuted = true;
//psuh the values to array
$cashflow_array[] = $dbData;
//break the loop
break;
}
}
//if not found in database
if(!$isExecuted){
$dbData['id'] = NULL;
$dbData['payment_date'] = $date->format("Y-m-d");
$d = new DateTime($date->format("Y-m-d"));
$dbData['day'] = $d->format('l');
$dbData['labour'] = 0;
$dbData['opening_balance'] = 0;
$dbData['other_income'] = 0;
$dbData['rent'] =0;
$dbData['electricity'] = 0;
$dbData['creditors'] = 0;
$dbData['insurance'] =0;
$dbData['direct_debits'] = 0;
$dbData['others'] = 0;
$dbData['total_amount'] = 0;
$dbData['updated_at'] = '';
$dbData['created_at'] = '';
$cashflow_array[] = $dbData;
}
}
}
return $cashflow_array;
}
you can achieve it easily by using a variable storing your current date, and double checking if the date is repeating or not.
For example:
//all the below code goes inside the foreach($cashflow as $cash)
//declare variable
$flag = false;
$counter = 0;
if($counter == 0)
{
$dt = new DateTime($date->format("Y-m-d"));
$curDate = $dt;
}else{
$dt = new DateTime($date->format("Y-m-d"));
}
if($curDate == $dt && counter !=0)
{
$flag = true;
}
$counter++;
//on your if conditions if($dt->format('l')!= 'Sunday' && $dt->format('l')!= 'SUNDAY' && $dt->format('l')!= 'SATURDAY' && $dt->format('l')!= 'Saturday')
//please add the condition:
&& flag == false

Not getting multiple records result in foreach

I am trying to get each objects points and finally I need to add those points.
I am using foreach loop, but I get only one objects points as a result.
Please help me to get all objects points as sum
MODEL:
public function getTransactionPoint($transactionId)
{
$transaction = Transaction::find($transactionId);
$transactionCoupon = TCoupon::where('transaction_id', '=', $transactionId)->first();
$transactionPoint = TPoint::where('transaction_id', '=', $transactionId)->first();
$pointType = PointType::find($this->pointUser->point_type_id);
//to get transaction details
$trans_detail = DB::table('jocom_transaction_details AS a')
->select('a.*', 'b.*')
->leftJoin('jocom_products AS b', 'a.sku', '=', 'b.sku')
->where('a.transaction_id', '=', $transactionId)->get();
//for bpoints
if($pointType->type == 'BCard' )
{
foreach ($trans_detail as $value)
{
$date1=$value->valid_from;
$date2=$value->valid_to;
$startdate=strtotime($date1);
$enddate=strtotime($date2);
$in_range=false;
$out_of_range=false;
$nodate=false;
$today1= date("Y-m-d");
$today=strtotime($today1);
if(($today >= $startdate) && ($today <=$enddate))
{
$in_range=true;
}
else
{
$in_range=false;
$out_of_range=true;
}
if($in_range)
{
if($value->multibpoints)
{
$points = $value->multibpoints *$value->price;
}
elseif($value->bpoints)
{
$points = $value->bpoints;
}
}
if($out_of_range)
{
$points = ($value->price) * $pointType->earn_rate;
}
if ($points - floor($points) > 0.99) {
return floor($points) + 1;
} else {
return floor($points);
}
}//endforeach
}else
//for jpoints
foreach ($trans_detail as $key=>$value) {
$date3=$value->valid_from;
$date4=$value->valid_to;
$startdatee=strtotime($date3);
$enddatee=strtotime($date4);
$in_rangee=false;
$out_of_rangee=false;
$nodatee=false;
$today3= date("Y-m-d");
$today4=strtotime($today3);
if(($today4 >= $startdatee) && ($today4 <=$enddatee))
{
$in_rangee=true;
}
else
{
$in_rangee=false;
$out_of_rangee=true;
}
if($in_rangee)
{
if($value->multijpoints)
{
$points = $value->multijpoints * $value->price;
}
elseif ($value->jpoints) {
$points = $value->jpoints;
}
}
if($out_of_rangee)
{
$points = ($value->price) * $pointType->earn_rate;
}
if ($points - floor($points) > 0.99) {
return floor($points) + 1;
} else {
return floor($points);
}
}
}
}
}
Suppose product A has 22 jpoints and 33 bpoints and product b has 10 jpooints and 12 bpoints, I am getting only points of A product, but I need output as sum of product a and product b points
am trying to get each objects points and finally i need to add those points .am using foreach loop .but i am getting only one objects points as a result please help me to get all objects points as sum``
If I've understood your question correctly, the reason you're only getting the results for one product is because you're using return inside the loop. Instead, you can define a variable called something like $totalPoints, add to it and then return that value after the loop e.g.
$totalPoints = 0;
foreach ($trans_detail as $value) {
//The rest of the code
if ($points - floor($points) > 0.99) {
$totalPoints += floor($points) + 1;
} else {
$totalPoints += floor($points);
}
}
return $totalPoints;
Also, you don't have to use this but it would appear you can greatly simplify your code:
public function getTransactionPoint($transactionId)
{
$pointType = PointType::find($this->pointUser->point_type_id);
$trans_detail = DB::table('jocom_transaction_details AS a')
->select('a.*', 'b.*')
->leftJoin('jocom_products AS b', 'a.sku', '=', 'b.sku')
->where('a.transaction_id', '=', $transactionId)->get();
$pointsName = $pointType->type == 'BCard' ? 'bpoints' : 'jpoints';
$totalPoints = 0;
$today = strtotime(date('Y-m-d'));
foreach ($trans_detail as $value) {
if ($today >= strtotime($value->valid_from) && $today <= strtotime($value->valid_to)) {
$points = $value->multibpoints ? $value->multibpoints * $value->price : $value->$pointsName;
} else {
$points = ($value->price) * $pointType->earn_rate;
}
$totalPoints += $points - floor($points) > 0.99 ? floor($points) + 1 : floor($points);
}
return $totalPoints;
}

Detecting a cycle in an array PHP

I'm running a simple script which puts an integer through the formula of the Collatz conjecture and adds the output of each step into an array.
I want to use a function to detect if there's a cycle in the array, using Floyd's algorithm. And though I feel like I'm not doing a bad job, I don't seem to get it right. At this moment I'm getting the error Trying to get property 'next' of non-object in C:\xampp\htdocs\educom\week3\functions.php on line 12
See my code below. Any feedback is greatly appreciated!
include("functions.php");
$n = $_POST['number'];
$step = 0;
$reeks1 = array();
$cycle = 0;
echo "Your entry is: ". $n ."<br><br>";
while($n!==1 && $cycle==0){
$cycle = detect_cycle(array($reeks1));
if($n % 2 == 0){
$n = $n / 2;
array_push($reeks1, "$n");
$step++;
echo $step .": ". $n ."<br>";
}else{
$n = ($n * 3) + 1;
array_push($reeks1, "$n");
$step++;
echo $step .": ". $n ."<br>";
}
}
functions.php:
function detect_cycle($node){
if ($node==NULL){
return FALSE;
}
$turtle = $node;
$rabbit = $node->next;
while($rabbit != NULL){
if($rabbit === $turtle){
return TRUE;
}elseif($rabbit->next == NULL){
return FALSE;
}else{
$turtle = $turtle->next;
$rabbit = $rabbit->next->next;
}
}
return FALSE;
}
Check this out. IMPORTANT I don't know is this according to your theory. but it won't give you errors if you use like this.
function detect_cycle($node){
if ($node==NULL){
return FALSE;
}
$turtle = $node;
$rabbit = $node[0];
while($rabbit != NULL){
if($rabbit === $turtle){
return TRUE;
}elseif($rabbit[0] == NULL){
return FALSE;
}else{
$turtle = $turtle[0]; // use the number of the element key starting from 0
$rabbit = $rabbit[0][1];
}
}
return FALSE;
}

Loop and AND conditional clause

I have had a hard time to get my head around this little piece of code.
protected function compressLowest($lowest){
$result = array();
$result['morning'] = array();
$result['afternoon'] = array();
$result['evening'] = array();
$result['allDay'] = array();
$type = $this->prices->getCondType();
$lastDate = 0;
$i = array();
$i['morning'] = $i['afternoon'] = $i['evening'] = $i['allDay'] = 0;
foreach($lowest as $date => $prices){
foreach($prices as $range => $price) {
if($this->isNextDay($date, $result[$range][$i[$range]]['to']) && $result[$range][$i[$range]]['price'] == $price){
$result[$range][$i[$range]]['to'] = $date;
} else {
$i[$range] = count($result[$range]);
$result[$range][] = array();
$result[$range][$i[$range]]['from'] = $date;
$result[$range][$i[$range]]['to'] = $date;
$result[$range][$i[$range]]['price'] = $price;
$result[$range][$i[$range]]['destime']=$this->arr['destime'];
$result[$range][$i[$range]]['deptime']=$this->arr['deptime'];
$result[$range][$i[$range]]['flight']=$this->arr['flight'];
}
}
$lastDate = $date;
}
//print_r($result);exit();
return $result;
}
And IsNextDay is checked as follows
protected function isNextDay($next, $day){
if($next - $day == 86400){ //60*60*24 = 86400
return true;
} else {
return false;
}
}
I can't figure out what is
isNextDay($date, $result[$range][$i[$range]]['to']) && $result[$range][$i[$range]]['price'] == $price) supposed to mean (the $day thing)?
in the if conditional clause of the second for-loop in the above function. Thank you if you could help me understand.
UPDATE
*Sorry I hadn't read it carefully until I discovered there was ) after the result[][]['to']... thanks for your concern.*
For the source code above, I always have a notice of UNDEFINED OFFSET 0. How to fix this bug-to-be ?
for your Undefined Offset 0 at the if line some index evaluates to 0 and the array you are using that index on does not have an element at that index.
For instance (I won't list all the possibilities) if $range is 0 and $result[0] is non-existent.

Show SINGLE RECORD with newest expiration date

I am using a FFDB database (flat File Database).
This script works as long as $vinc field has the same value, but I have 5 different types of $vinc values R1, R2, R3, R4, R5 - if I add new record where $vinc is not R1, a blank page appears instead.
<?php
function getbyfunction($selectfn, $orderby = NULL, $includeindex = false)
{
if (!$this->isopen)
{
user_error("Database not open.", E_USER_ERROR);
return false;
}
// If there are no records, return
if ($this->records == 0)
return array();
if (!$this->lock_read())
return false;
// Read the index
$index = $this->read_index();
// Read each record and add it to an array
$rcount = 0;
foreach($index as $offset)
{
// Read the record
list($record, $rsize) = $this->read_record($this->data_fp, $offset);
// Add it to the result if the $selectfn OK's it
if ($selectfn($record) == true)
{
// Add the index field if required
if ($includeindex)
$record[FFDB_IFIELD] = $rcount;
$result[] = $record;
}
++$rcount;
}
$this->unlock();
// Re-order as required
if ($orderby !== NULL)
return $this->order_by($result, $orderby);
else
return $result;
}
function returnRec($item){
if($item)
return true;
}
$db = new FFDB();
if (!$db->open("foo"))
{
$schema = array(
array("key", FFDB_INT, "key"),
array("status", FFDB_STRING),
array("vinc", FFDB_STRING),
array("month", FFDB_STRING),
array("day", FFDB_INT),
array("year", FFDB_INT)
);
// Try and create it...
if (!$db->create("foo", $schema))
{
echo "Error creating database\n";
return;
}
}
$result = $db->getbyfunction("returnRec", "vinc");
show_rec(end($result));
function show_rec($record){
$number = $record["key"];
$Rvinc = $record["vinc"];
$Rstatus = $record["status"];
$Rday = $record["day"];
$Rmonth = $record["month"];
$Ryear = $record["year"];
$tday = getdate();
$current_year = $tday['year'];
$current_month = $tday['month'];
if (($status == ON) && ($vinc == R1) && ($month >= $current_month) && ($year == current_year)){
echo "myrecord $vinc $status $day $month $year";
}
?>
Any help?!
Thanks
Yegge, using show_rec($result[0]); it shows 1 record but instead the most recent expiration date is showing the latest expiration date:
i.e.:
1 record expire 08/01/2011
2 record expire 11/01/2011
show_rec($result[0]); is showing the record with expiration date 11/01/2011 instead of 08/01/2011
Yegge
show_rec(end($result)); worked as long as $vinc == R1 only, if adding another record where vinc is not R1 then shows a blank page, any ideas?
<?php
function getbyfunction($selectfn, $orderby = NULL, $includeindex = false)
{
if (!$this->isopen)
{
user_error("Database not open.", E_USER_ERROR);
return false;
}
// If there are no records, return
if ($this->records == 0)
return array();
if (!$this->lock_read())
return false;
// Read the index
$index = $this->read_index();
// Read each record and add it to an array
$rcount = 0;
foreach($index as $offset)
{
// Read the record
list($record, $rsize) = $this->read_record($this->data_fp, $offset);
// Add it to the result if the $selectfn OK's it
if ($selectfn($record) == true)
{
// Add the index field if required
if ($includeindex)
$record[FFDB_IFIELD] = $rcount;
$result[] = $record;
}
++$rcount;
}
$this->unlock();
// Re-order as required
if ($orderby !== NULL)
return $this->order_by($result, $orderby);
else
return $result;
}
function returnRec($item){
if($item)
return true;
}
$db = new FFDB();
if (!$db->open("foo"))
{
$schema = array(
array("key", FFDB_INT, "key"),
array("status", FFDB_STRING),
array("vinc", FFDB_STRING),
array("month", FFDB_STRING),
array("day", FFDB_INT),
array("year", FFDB_INT)
);
// Try and create it...
if (!$db->create("foo", $schema))
{
echo "Error creating database\n";
return;
}
}
$result = $db->getbyfunction("returnRec", "vinc");
foreach($result as $item) {show_rec($item);break;}
function show_rec($record){
$number = $record["key"];
$Rvinc = $record["vinc"];
$Rstatus = $record["status"];
$Rday = $record["day"];
$Rmonth = $record["month"];
$Ryear = $record["year"];
$tday = getdate();
$current_year = $tday['year'];
$current_month = $tday['month'];
if (($status == ON) && ($vinc == R1) && ($month >= $current_month) && ($year == current_year)){
echo "myrecord $vinc $status $day $month $year";
}
?>
i think you need to use break in loop, like above.
select product, expirationdate from your_table
where expirationdate > {current_date} order by expirationdate ASC limit 1
{current_date} is variable that should be passed from php or you can use mysql function instead
If I understood your code correctly, instead of
foreach($result as $item) {show_rec($item);break;}
//use
show_rec($result[0]); //only show the very first item in the result array
Edit: Then use this:
show_rec(end($result));
SOLUTION:
I just want to make sure to post the solution:
$result = $db->getall(lp_month,lp_year);
$i = 0;
foreach ($result as $row){
print_r (show_record($row));
if ($i >= 1)
break;
$i++;
}
Not a lot different from what I initially had, but print_r instead of echo did the trick:
print_r (show_record($row));
Thanks

Categories