Data Pass from controller to view - php

I want to display the sum of column debit. When I pass data after sum value of the debit column and store it in a variable, I pass the data from controller to my view but laravel says it's undefined. Can anyone help me with this?
View.blade.php
<tr>
<th>Total Debit:</th>
<td>
#foreach ($totaldebit as $tdebit)
{{ $tdebit }}
#endforeach
</td>
</tr>
UserController.php
$tdebit = DB::table('debitemps')->sum('debit');
return view('pages/payments/debit/debit', [
'workerlists' => $data,
'debitid' => $id,
'Empdebitdata' => $dataEmp,
'totaldebit' => $tdebit
]);

Related

Save date into database with Carbon

I'm still new in Laravel. Currently, I'm learning and working on Carbon. I already looking on every documentation and other solution but I still don't get it. I hope there is someone can teach and show me step by step how to correct or improve my code.
ComplaintController.php
public function store(Request $request)
{
if (count($request->defect_id) > 0) {
foreach($request->defect_id as $item=>$v) {
$data = array(
'defect_id' => $request->defect_id[$item],
'image' => $filename,
'description' => $request->description[$item],
'report_by' => Auth::user()->id,
'created_at' => Carbon::today()->toDateString(),
'updated_at' => Carbon::now()->toDateTimeString()
);
Complaint::insert($data);
I'm saving created_at field as date only, no time and it is in the format of (yy-mm-dd).
index.blade.php
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>Defect Name</th>
<th>Description</th>
<th>Image</th>
<th>Report Date</th>
<th>Due Date</th>
</tr>
</thead>
#foreach($complaint as $c)
<tr>
<td>{{$c->defect->name}}</td>
<td>{{$c->description}}</td>
<td><img src="{{ Storage::url('complaint/' . $c->image)}}" class="" alt="{{$c->image}}"></td>
<td>{{$c->created_at->toDateString()}}</td>
<td></td>
</tr>
#endforeach
</table>
</div>
My date is still showing finely in the table as (yy-mm-dd) but I want the date to be in format of (dd/mm/yy) so I try to use this kind of code {{$c->created_at->toDateString()->format("dd/mm/yy")}} and there is error appeared which is Call to a member function format() on string. Later on, I need to add another field for duedate and use this function addDays(30). So, what I need to do? I'm guessing that I need to put another function in my model but I can't figure out how to do it.
As mentioned by #Tim Lewis as well,
replace
{{ $c->created_at->toDateString()->format("dd/mm/yy") }}
to
{{ $c->created_at->format("dd/mm/yy") }}
As toDateString() converts it to string before changing the format.
You can also try using standard php format for datetime, instead of Carbon class,
{{ date("d/m/Y", strtotime($c->created_at)) }}
As for your second question of you want to add new table data column ,
<tr>
<td>{{ $c->defect->name }}</td>
<td>{{ $c->description }}</td>
<td><img src="{{ Storage::url('complaint/' . $c->image)}}" class="" alt="{{$c->image}}"></td>
<td>{{ $c->created_at->format("dd/mm/yy") }}</td>
<td>{{ $c->created_at->addDays(30) }}</td>
</tr>
This should work...
To save the date in the format dd/mm/yy, I would use the following:
date('d-m-Y', strtotime(Carbon\Carbon::now()))
To reformat the date in a view, I would use:
date('d-m-Y', strtotime($c->created_at))
I prefer to use the base php functions wherever possible to keep things simple.
If someone knows a reason not to, please let me know.
As for the adding of days,
date('d-m-Y', strtotime($c->created_at) + (60 * 60 * 24 * 30))
Should work.
Most date related problems can be solved with strtotime(), its very useful. Be sure to read up on it here: https://www.php.net/manual/en/function.strtotime.php
Casted date fields:
In Laravel the created_at and updated_at fields are casted as date fields already. So you don't have to transform this into date formats.
You can simply do
<td>{{ $c->created_at->format("d/m/y") }}</td>
Fields created_at and updated_at are also automatically filled
So you don't need to fill this fields
You can simply do
$data = array(
'defect_id' => $request->defect_id[$item],
'image' => $filename,
'description' => $request->description[$item],
'report_by' => Auth::user()->id,
);
Complaint::create($data);
Extra date field duedate
When you add custom date fields you need to cast them in the model to be date.
Add this in you model:
protected $dates = ['duedate'];

Laravel - Update multiple rows value with a form

I am listing many rows in a table and I AM trying to edit them with a drop down menu that exists in each row. The code below is fine but it will store only the last (S_Rank) value (which is the column I want to change) what would be the best way to get each row input. I know the issue that the form is not an array, what would be the way to make it an array
My view
{!! Form::open(['action' => 'AbstractsController#UpdateRank' , 'method' => 'post' ]) !!}
<table id="myTable" class ="table table-striped">
<thead>
<td><h4>Student Name</h4></td>
<td><h4>Student Rank</h4></td>
</thead>
#foreach($applications as $application)
<tbody>
<tr>
<td><h5>{{$application->Student_Name}}</h5></td>
<td><h5>
{{Form::select('Ranking' ,$ranks, ['class' => 'form-control', 'placeholder' =>$application->S_Rank] )}}
{{Form::hidden('Student_ids[]', $application->S_ID)}}
</h5></td>
</tr>
#endforeach
</tbody>
</table>
{{Form::Submit('Save New Ranking',['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
My controller
foreach(request('Student_ids') as $S_ID){
$application = Application::where('S_ID' , $S_ID)->get();
$application->S_Rank = $request-> input('Ranking');
$application->save();}
I am trying to update each row with the inputted value from each dropdown menu
I think you already answer yourselve. I think what you need is to change your $ranks var to $ranks[] because you are actually only taking the last value they chose in your select, that way, you are storing your ranks in a one dimenssion array that should correspont with your Student_ids[] hidden array
If you want to update the ranking per application, you'll need to know which ranking value goes to which application. Assuming S_ID is a unique identifier for Application, you could do something like this in your view:
<h5>
{{Form::select('Ranking[' . $application->S_ID . ']' ,$ranks, ['class' => 'form-control', 'placeholder' =>$application->S_Rank] )}}
</h5>
Then in your controller:
foreach(request('Ranking') as $S_ID => $rank){
$application = Application::where('S_ID' , $S_ID)->first();
$application->S_Rank = $rank;
$application->save();}

Laravel collection turns empty inside foreach loops

I have 3 collections on different items that I need to show and group by date, in the blade file I loop over the dates to show these collections, but for some reason whatever the first collection is, something wrong happens with it, it shouldn't change based on the date, let's say I have two dates (2019-03, 2019-01), I end up with two different instances of the same collection, one with the data, and one without(an empty collection), even though I am calling the same variable.
The controller method:
public function index()
{
//Retrieving the Models.
$invoices_egp = auth()->user()->invoices()->where('paid', 1)->where('currency', 'EGP');
$invoices_usd = auth()->user()->invoices()->where('paid', 1)->where('currency', 'USD');
$orders = \App\Order::where('vendor_id', auth()->user()->id)->where('paid', 1);
//Getting the different dates of these Models.
$egp_invoices_dates = $invoices_egp->get()->map(function ($invoice) {
return Carbon::parse($invoice->created_at)->format('Y-m');
});
$usd_invoices_dates = $invoices_usd->get()->map(function ($invoice) {
return Carbon::parse($invoice->created_at)->format('Y-m');
});
$orders_dates = $orders->get()->map(function ($order) {
return Carbon::parse($order->created_at)->format('Y-m');
});
//Getting the unique dates.
$dates = $orders_dates->merge($usd_invoices_dates)->merge($egp_invoices_dates)->unique();
return view('dashboard.vendor.reports.index', compact('invoices_egp', 'invoices_usd', 'orders', 'dates'));
}
The relevant part of the blade file:
<div class="col-lg-12">
#if ( count( $dates ) )
#foreach($dates as $date)
<div class="card-box">
<div class="table-responsive">
<table class="table table-actions-bar m-b-0">
<thead>
<tr>
<th>
Month
</th>
</tr>
<tr>
<td>
{{ $date }}
</td>
</tr>
</thead>
<tbody>
<tr>
<th colspan="100%">Type</th>
<th>Total</th>
</tr>
<tr>
#if(count($invoices_egp->get()))
<td colspan="100%">Invoice in EGP</td>
<td>{{ $invoices_egp->whereYear('paid_at', \Carbon\Carbon::parse($date)->year)->whereMonth('paid_at', \Carbon\Carbon::parse($date)->month)->sum('total') }}</td>
#endif
</tr>
<tr>
#if(count($invoices_usd->get()))
<td colspan="100%">Invoice in USD</td>
<td>{{ $invoices_usd->whereYear('paid_at', \Carbon\Carbon::parse($date)->year)->whereMonth('paid_at', \Carbon\Carbon::parse($date)->month)->sum('total') * \App\ConversionRate::dollarToEGP() }}</td>
#endif
</tr>
<tr>
#if(count($orders->get()))
<td colspan="100%">Orders</td>
<td>{{ $orders->whereYear('paid_at', \Carbon\Carbon::parse($date)->year)->whereMonth('paid_at', \Carbon\Carbon::parse($date)->month)->sum('total') }}</td>
#endif
</tr>
</tbody>
</table>
</div>
</div>
#endforeach
#else
<div class="card-box">
<h3>No Data</h3>
</div>
#endif
</div>
Here when I loop over the $dates variable, for some reason, the $invoices_egp variable changes based on the date, even though it has got nothing to do with it, if I tried to dump $invoices_egp (which has two records with the same date 2019-01) on each loop, I am expecting to get the two records twice regardless of the date, instead I get the two records on the first loop ($date = 2019-03), and on the second loop ($date = 2019-01) I get an empty collection.
I have tried different stuff, I replaced the dates variable with a hard coded array and removed the other dates queries, nothing changes in the blade file.
What's even weirder is that if I changed the place of $invoices_egp with $invoices_usd, I get $invoices_egp rendered correctly, and the bug instead happens to the $invoices_usd variable, so whatever the first variable is, it gets messed up.
Small Update
I don;t know what's wrong yet, but as soon as I comment out this line
<td>{{ $invoices_egp->whereYear('paid_at', \Carbon\Carbon::parse($date)->year)->whereMonth('paid_at', \Carbon\Carbon::parse($date)->month)->sum('total') }} EGP</td>
I get the variable rendering twice correctly per each instance of the loop, which is what should happen, and this line I am commenting should not have any impact over whether the collection should be retrieved successfully or not, I hope I am making sense.
If I dump the variable over each loop, this is what I get in the first loop
Collection {#522 ▼
#items: array:2 [▼
0 => Invoice {#526 ▶}
1 => Invoice {#519 ▶}
]
}
And this is what I get in the second loop (with the aforementioned line uncommented)
Collection {#516 ▼
#items: []
}
Same variable, different results over a loop.
So apparently since I was passing a query builder instance to the view, it was actually getting changed by the foreach loop, which is something I'd never thought would happen, anyway the fix was easy at that point, just had to change the code a little, starting from here:
public function index()
{
$invoices_egp = auth()->user()->invoices()->where(['paid' => 1, 'currency' => 'EGP'])->latest()->get();
$invoices_usd = auth()->user()->invoices()->where(['paid' => 1, 'currency' => 'USD'])->latest()->get();
$orders = \App\Order::where('vendor_id', auth()->user()->id)->where('paid', 1)->latest()->get();
$egp_invoices_dates = $invoices_egp->map(function($invoice) { return Carbon::parse($invoice->paid_at)->format('Y-m'); })->unique();
$usd_invoices_dates = $invoices_usd->map(function($invoice) { return Carbon::parse($invoice->paid_at)->format('Y-m'); })->unique();
$orders_dates = $orders->map(function($order) { return Carbon::parse($order->paid_at)->format('Y-m'); })->unique();
$dates = $orders_dates->merge($usd_invoices_dates)->merge($egp_invoices_dates)->unique();
return view('dashboard.vendor.reports.index', compact('invoices_egp', 'invoices_usd', 'orders', 'dates'));
}
And in the view I just had to change the filtering queries to be like this for all 3 queries:
<td>{{ $invoices_egp->filter(function($invoice) use ($date) { return $invoice->created_at->year == \Carbon\Carbon::parse($date)->year; })->filter(function($invoice) use ($date) { return $invoice->created_at->month == \Carbon\Carbon::parse($date)->month; })->sum('total') }} EGP</td>

Laravel - Append row id to form name attribute inside each row of a dynamic table

I send two variable to my view $abilities, and $users. $abilities is an array of key-value pairs containing data in the following format:
["1"=>"create_user","2"=>"delete_user","3"=>"ban_user"]
$users is an array in the following format:
["1"=>"John Doe","2"=>"Jane Doe"]
Both are taken from their respective databases abilities (columns: ID, name) and users (columns: ID, name).
In the view, I have a table which contains a multiple select for each row against the $user->id:
#foreach($users as $user)
<tr>
<td>{{$user->id}}</td>
<td>
{{Form::select("takenabilities[]",$abilities, null, ['id'=>'system-abilities','multiple','class'=>'form-control' ])}}
</td>
</tr>
#endforeach
Problem is that when I receive the request in my controller, I only see one takenabilities[] array, and I want to save data from each multiple select in each row generated dynamically, if that makes sense?
You can't do that using multiple selects with the same name. The value of the last one overrides all previous selects' values. In addition you'd better assign different id to every select. Try to add another level to the array:
#foreach($users as $user)
<tr>
<td>{{$user->id}}</td>
<td>
{{Form::select("takenabilities[$user->id][]", $abilities, null, ['id'=>'system-abilities-' . $user->id,'multiple','class'=>'form-control' ])}}
</td>
</tr>
#endforeach
And in controller:
$takenabilities = [];
foreach(Request::input('takenabilities') as $userId => $userAbilities) {
$takenabilities = array_merge($takenabilities, $userAbilities);
}
$takenabilities = array_unique($takenabilities);

Adding multiple values into Session to insert in a pivot table

I have three tables delivery-request_item, items and a pivot table delivery-request_item. In my create.blade.php, I have button, which will add one of the items with its corresponding quantity selected by the user.
My solution was to put the item and quantity to the Session. Now my problem is that I can only create one record, if I decided to add another item, the previous item gets overridden.
create.blade.php
{{Form::open(array('method'=>'POST','url'=>'delivery-requests'))}}
{{Form::text('requested_by', Auth::user()->email)}}
<div>
{{Form::label('Shows Items from table')}}
{{Form::select('item_id', $items)}}
{{Form::label('Quantity')}}
{{Form::text('item_quantity')}}
{{Form::submit('add item',array('name'=>'addItem'))}}
{{Form::submit('remove item', array('name' => 'removeItem'))}}
</div>
<hr>
<div>
<table>
<theader>
<tr>
<td>ITEM NAME</td>
<td>QUANTITY</td>
</tr>
</theader>
<!-- loop through all added items and display here -->
#if(Session::has('item_id'))
<h1>{{ Session::get('item_id') }}</h1>
#endif
#if(Session::has('item_quantity'))
<h1>{{ Session::get('item_quantity')}}</h1>
#endif
</table>
</div>
{{Form::submit('submit', array('name' => 'submit'))}}
{{Form::close()}}
DeliveryRequestsController#Store
if(Input::has('addItem'))
{
Session::flash('item_id', Input::get('item_id'));
Session::flash('item_quantity', Input::get('item_quantity'));
$data = Session::all();
$item = Item::lists('item_name','id');
return View::make('test')->with('data',$data)->with('items',$item);
}
Two things.
You need to make the session an array, otherwise you'll always overwrite.
You need to not use flash() as this data will be removed as soon as another request is made, that's what flash data is, data that persists until the next request.
Try this:
if(Input::has('addItem')) {
if(Session::has('items')) {
Session::push('items', [
'id' => Input::get('item_id'),
'qty' => Input::get('item_quantity')
]);
} else {
Session::put('items', [
'id' => Input::get('item_id'),
'qty' => Input::get('item_quantity')
]);
}
}
Session::push() works with arrays stored in a session, and then obviously Session::put() is used if it doesn't exist.
Remember that this data will be persist, and will need to be cleared upon certain instances, like once you've finished with it.
For more information about sessions, read this: http://laravel.com/docs/session

Categories