Laravel Excel export - laravel

While exporting the data, it seemed to add the conditions for exporting. So, I made the constructor method and passed the data from the controller.
public function __construct($company_pan, $user_pan)
{
$this->company_pan = $company_pan;
$this->user_pan = $user_pan;
}
public function collection()
{
return PurchaseDetail::where([
['pan_code', $this->user_pan],
['s_pan', '=', $this->company_pan]
])->get();
}
In the Controller,
public function export(Request $request)
{
$company_pan = $request->pan;
$user_pan = Auth::user()->pan_code;
return Excel::download(new ConfirmationExport($company_pan, $user_pan), 'Confirmation.xlsx');
}
All the output is blank excel. But if I changed the code in the collection of s_pan as
public function collection()
{
return PurchaseDetail::where([
['pan_code', $this->user_pan],
['s_pan', '=', '303030333']
])->get();
}
It exports the data as expected. What actually the problem is?

Have you defined the attributes of your class? Like this?
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
class ExampleExport implements FromCollection
{
protected $company_pan;
protected $user_pan;
public function __construct($company_pan, $user_pan)
{
$this->company_pan = $company_pan;
$this->user_pan = $user_pan;
}
public function collection()
{
return PurchaseDetail::where([
['pan_code', $this->user_pan],
['s_pan', '=', $this->company_pan]
])->get();
}
}

Related

Laravel excel export how to export conditional data?

I am trying to export partial data from my table not all data, I am using Maatwebsite plugin
I have tried below code in controller
public function report(Request $request)
{
$sdate = $request->query('sdate');
$edate = $request->query('edate');
$report = Report::whereDate('created_at', '>=', $sdate)
->whereDate('created_at', '<=', $edate)
->get();
return Excel::download($report, 'report.xlsx');
}
In this time I am getting empty excel file.
I am able to get all data after creating app/export
like below
app/export/ReportExport.php
public function collection()
{
return Report::all();
}
but how I can I do it in controller ? or how can I sent $report data controller to collection ?
You can use the FromQuery concern provided by the package.
namespace App\Exports;
use App\Report;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
class ReportExport implements FromQuery
{
use Exportable;
public function __construct($start, $end)
{
$this->start = $start;
$this->end = $end;
}
public function query()
{
return Report::query()->whereDate('created_at', '>=', $this->start)
->whereDate('created_at', '<=', $this->end);
}
}
Then from you controller, you can call it
return (new ReportExport($sdate, $edate))->download('report.xlsx');
I have not tested the code. So apologies if I made a mistake. You can refer to official documentation.
There are also other methods of exporting which you can find from the documentation.
you can do it by doing this way.
Step 1: in your controller
bind $request in Report-Export Class. add code in method where you are calling export excel.
return Excel::download(new ReportExport($request), 'report.xlsx');
step 2:
protected $request;
public function __construct($request)
{
$this->request = $request;
}
public function collection()
{
$request = $this->request ;
return User::where('customer_id',$request->cId)->get();
}

Use the attribute of a model in a scope

I have defined an attribute in my model and want to use it in a scope.
protected $appends = ['lowest_price'];
public function getLowestPriceAttribute()
{
$lowest_price = NULL;
foreach($this->shops as $shop) {
if(is_null($lowest_price)) {
$lowest_price = (double)$shop->pivot->price;
}
if($lowest_price > (double)$shop->pivot->price) {
$lowest_price = (double)$shop->pivot->price;
}
}
return $lowest_price;
}
The lowest_price attribute I would like to use in a scope but it's always 'null':
public function scopeMaxPrice(Builder $query, $max_price): Builder {
return $query->where('max_price', '>=', $this->lowest_price);
}
If I dd(); the getLowestPriceAttribute function in the scope it also returns 'null'. In my view I have access to the 'lowest_price' attribute.
Can the attribute be part of the query? If not, is there an elegant solution?
EDIT: The scope gets called in the Product controller:
public function index()
{
$products = QueryBuilder::for(Product::class)
->allowedFilters(
AllowedFilter::exact('type_id')->default('1'),
AllowedFilter::scope('min_speed')->default(0),
AllowedFilter::scope('min_range')-> default(0)
# AllowedFilter::scope('max_price')-> default(999)
)
->get();
$types = DB::table('types')->pluck('name', 'id');
return view('pages.home', compact('products', 'types'));
}
Note: I am using the Spatie querybuilder

How to add custom methods to eloquent model in a way we can chain them?

What I want is add methods to eloquent models so I can chain them, for example:
class MovieResolver
{
public function getMoviesFeaturingToday(array $args)
{
// Movie is an Eloquent model
$movie = (new Movie())
->getMoviesFeaturingTodayOnTheater($args['movieTheaterId'])
->getBySessionCategory($args['sessioncategory']);
// And keep doing some operations if necessary, like the code below.
// I cannot call the get() method unless I finish my operations.
return $movie->whereDate('debut', '<=', Carbon::today())
->orderBy('debut', 'desc')
->get();
}
}
But adding these methods to the model:
class Movie extends Model
{
public function getMoviesFeaturingTodayOnTheater($theaterId)
{
return $this->whereHas(
'sessions.entries.movieTheaterRoom',
function ($query) use ($theaterId) {
$query->where('movie_theater_id', $theaterId);
}
);
}
public function getBySessionCategory($sessionCategory)
{
return $this->whereHas(
);
}
}
Results in the following error:
Call to undefined method Illuminate\Database\Eloquent\Builder::getMoviesFeaturingTodayOnTheater()
But why? What I'm doing wrong?
This is done using Query Scopes. So try this in your model instead:
public function scopeMoviesFeaturingTodayOnTheater($query, $theaterId)
{
return $query->whereHas(
'sessions.entries.movieTheaterRoom',
function ($query) use ($theaterId) {
$query->where('movie_theater_id', $theaterId);
}
);
}
public function scopeBySessionCategory($query, $sessionCategory)
{
return $query->whereHas(
// ...
);
}
Then to use it you do:
Movie::moviesFeaturingTodayOnTheater($args['movieTheaterId'])
->bySessionCategory($args['sessioncategory']);;

how to use laravel Scope in a relationship?

I'm using laravel
I have two models
Product
class Product extends Model
{
public function productcategories(){
return $this->hasOne('App\Product\Productcategorie','CategoryID','ProductCategoryId');
}
}
and Productcategorie
class Productcategorie extends Model
{
protected $primaryKey = 'CategoryID';
public function product(){
return $this->belongsToMany('App\Product\Product','ProductCategoryId','CategoryID');
}
public function scopeCp($query,$id){
return $query->where('categoryparent_id', '=', $id);
}
}
The Product model has a scope Cpscope
and i have ProductController with function
function productCatgoryPaFilter(Request $request){
$categories= Categoryparent::with('categories')->get();
$id=$request->id;
return $product = Product::with('productcategories')->with('productoption.option')->orderBy('created_at','DESC')->get();
}
i want to get all products with categoryparent_id equal to passed parametre in scope
how can i do it?
If you want to filter data in relational model, use whereHas(). Though i have not tested, give it a try
Product::whereHas('productcategories', function ($query) use($id) {
$query->cp($id);
})
->orderBy('created_at','DESC')->get()

Get onlyTrashed() does not exist in query builder

I am trying to get trashed rows from table messages:
public function trash() {
return $this->onlyTrashed()
->where('user_id', '=', $this->_u)
->orWhere('receiver', '=', $this->_u)
->orderBy('deleted_at', 'desc')->get();
}
I get this error:
Method Illuminate\Database\Query\Builder::onlyTrashed does not exist.
I checked up Builder and SoftDeletes files for onlyTrashed method and it does not exist, how can I look up to trashed messages from message table?
The only way I think about is to create method that doesn't return messages where delete_at is not null and for trashed to return only those where it is not null. But I am still wondering why this doesn't work since it is in documentation at this url:
https://laravel.com/docs/5.6/eloquent#soft-deleting
MORE INFO
Yes it is inside model and yes I added use SoftDeletes:
use Illuminate\Database\Eloquent\SoftDeletes; - on top
use SoftDeletes; after opening the class
Let me paste entire model here:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;
class Messages extends Model
{
use SoftDeletes;
protected $fillable = [
'user_id', 'subject', 'text', 'receiver'
];
public $_u;
protected $dates = ['deleted_at'];
public function __construct() {
$this->_u = auth()->user()->user_id; //or some id as string
}
public function trash() {
return $this->onlyTrashed()
->where('user_id', '=', $this->_u)
->orWhere('receiver', '=', $this->_u)
->orderBy('deleted_at', 'desc')->get();
}
public static function trashed() {
return self::onlyTrashed();
}
}
And controller has:
public function __construct() {
$this->middleware('auth');
}
public function index($field = 'trash') {
if ($field !== "new") {
$messages = (new Msg)->$field();
$user = auth()->user();
return view('pages.messages', compact('messages', 'user'));
}
return view('pages.messages.new', compact('messages', 'user'));
}
I tried calling static as well and I tried doing it from tinker and still keep getting:
onlyTrashed() doesn not exist
You have to call the parent constructor:
public function __construct() {
parent::__construct();
$this->_u = auth()->user()->user_id;
}
I think what you want is to define the trash method static:
public static function trash() {
return self::onlyTrashed()
->where('user_id', '=', $this->_u)
->orWhere('receiver', '=', $this->_u)
->orderBy('deleted_at', 'desc')->get();
}
Then call this function by:
$messages = Messages::trash();
This should work
# YourModelController.php
/**
* Show only trashed
*
* #return \Illuminate\Http\Response
*/
public function trashed()
{
...
$trashed = YourModel::onlyTrashed()->get();
...
}
I have researched a little further and I got this:
From https://laravel.com/api/5.6/Illuminate/Database/Eloquent.html
I should have
SoftDeletesTrait
but I have
SoftDeletes
. In softdeletestrait we have onlyTrashed method but in SoftDeletes we do not.
So I copied that method from this page:
https://github.com/laravel/framework/blob/7d9e7068c49f945385673014d4cba4de28accd5e/src/Illuminate/Database/Eloquent/SoftDeletingTrait.php#L119
And added it to SoftDeletes class, now it works like it should. I haven't find why it doesn't exist inside SoftDeletes class so if anyone find out let us know!

Resources