The work of this function is to generate report of specific condition. Thus i am generating report with two tables ( User and Booking ) With primary key is userid and bookingid. Both the table is be clubbed into relations. Now i want to generate excel with using maatwebsite package at this condition. From (booking table) and to (booking table) with ticketstatus (booking table) and also with usertype ( from usertable ). For example From 01.09.2018 to 23.09.2018 with ticket status as "booked " and usertype as "Normal or agent". But i am getting an error, i am using FromQuery method in maatwebsite to perform this function.
I am adding all the codes here, User Model :
<?php
namespace App;
use App\Booking;
use App\Wallet;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $primaryKey = 'userid';
protected $fillable = ['name', 'phone', 'email','password','usertype'];
protected $dates = [
'createdAt'
];
const CREATED_AT = 'createdAt';
const UPDATED_AT = 'updatedAt';
public function bookings()
{
return $this->hasMany('App\Booking', 'userid');
}
public function walletUsers()
{
return $this->hasOne('App\Wallet', 'userid');
}
public function supports()
{
return $this->hasMany('App\Help', 'userid');
}
public function getNameAttribute($value)
{
return ucfirst($value);
}
}
Booking Model :
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Booking extends Model
{
protected $primaryKey = 'bookingid';
protected $dates = [
'createdAt','updatedAt'
];
const CREATED_AT = 'createdAt';
const UPDATED_AT = 'updatedAt';
public function users()
{
return $this->belongsTo('App\User', 'userid');
}
public function getDateOfIssueAttribute($value) {
return Carbon::parse($value)->format('d-M-Y , h:m a');
}
public function getDateOfCancellationAttribute($value) {
return Carbon::parse($value)->format('d-M-Y , h:m a');
}
public function getDojAttribute($value) {
return Carbon::parse($value)->format('d-M-Y , h:m a');
}
}
Now Controller :
public function report(Request $request){
$from = $request->from;
$to = $request->to;
$bookingtype = $request->bookingtype;
$usertype = $request->usertype;
return (new BookingsExport($from, $to, $bookingtype, $usertype))->download('invoices.xlsx');
}
Route :
Route::post('/admin/reports/collect',[
'uses' => 'ReportController#report',
'as' => 'reports.generate'
]);
Maatwebsite Class:
<?php
namespace App\Exports;
use App\Booking;
use App\User;
use Carbon\Carbon;
use App\Http\Controllers\ReportController;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithMapping;
class BookingsExport implements FromQuery, WithStrictNullComparison, WithHeadings, ShouldAutoSize, WithColumnFormatting, WithMapping {
use Exportable;
public function __construct($from, $to, $bookingtype, $usertype)
{
$this->from = $from;
$this->to = $to;
$this->bookingtype = $bookingtype;
$this->usertype = $usertype;
}
public function headings(): array
{
return [
'Booking Id',
'Block Key',
'Bus Type',
'DOJ',
'status',
'Created At',
'Updated At',
'Usertype',
'Name'
];
}
public function map($booking): array
{
return [
$booking->bookingid,
$booking->blockkey,
$booking->busType,
$booking->doj,
$booking->status,
$booking->createdAt,
$booking->updatedAt,
$booking->users->usertype,
$booking->users->name
];
}
public function columnFormats(): array
{
return [
'D' => 'dd-mm-yyy',
'E' => NumberFormat::FORMAT_DATE_DDMMYYYY
];
}
public function query()
{
$from = $this->from;
$to = $this->to;
$bookingtype = $this->bookingtype;
$usertype = $this->usertype;
if(isset($from) && isset($to) && is_null($bookingtype) && is_null($usertype))
{
return Booking::query()->whereBetween('createdAt',[$from, $to]);
}
if(isset($from) && isset($to) && isset($bookingtype) && is_null($usertype))
{
return Booking::query()->whereBetween('createdAt',[$from, $to])->where('status','=', $bookingtype);
}
if(isset($from) && isset($to) && isset($bookingtype) && isset($usertype))
{
return Booking::query()->with('users')->whereHas("users", function($subQuery){
$subQuery->where("usertype", "=", $usertype);})->whereBetween('createdAt',[$from, $to])->where('status','=', $bookingtype);
}
}
}
The error i am getting is "Undefined variable: usertype" from the last query of Maatwebsite class file. But i am seeding all the values from controller to this, i even dd($usertype) but i am getting the value as agent, but it shows error while using in it query ! Kindly guide
Related
I have been trying to create a point system, so after much effort i am getting this error which i could not figure out how to solve it because this is my first time working so deep
I have checked code but couldn't pinpoint the error
call to undefined app\models\User:id()
point model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class Point extends Model
{
use HasFactory;
const TABLE = 'points';
protected $table = self::TABLE;
protected $fillable = [
'id', 'amount', 'message', 'current_points'
];
public function pointable(): MorphTo
{
return $this->morphTo();
}
public function getCurrentPoints(Model $pointable)
{
$currentPoints = Point::where('pointable_id', $pointable->id())
->where('pointable_type', $pointable->getMorphClass())
->orderBy('created_at', 'desc')
->pluck('current_points')->first();
if($currentPoints){
$currentPoints = 0;
}
return $currentPoints;
}
public function addAwards(Model $pointable, $amount, $message)
{
$award = new Static();
$award->amount = $amount;
$award->current_points = $this->getCurrentPoints($pointable) + $amount;
$award->message = $message
$pointable->awards()->save($award);
return $award;
}
}
pointable model
<?php
namespace App\Models;
interface pointable
{
public function awards();
public function countAwards();
public function addPoints($amount, $message);
}
hasPoints Traits
<?php
namespace App\Traits;
use App\Models\Point;
trait HasPoints
{
public function awards($amount = null)
{
return $this->morphMany(Point::class, 'pointable')
->orderBy('created_at', 'desc')
->take($amount);
}
public function countAwards()
{
return $this->awards()->count();
}
public function currentPoints()
{
return (new Point())->getCurrentPoints($this);
}
public function addPoints($amount, $message)
{
return (new Point())->addAwards($this, $amount, $message);
}
}
AwardPointLItener
?php
namespace App\Listeners;
use App\Events\ReplyWasCreated;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class AwardPointForNewReply
{
public function handle(ReplyWasCreated $event)
{
$amount = config('points.rewards.new_reply');
$message = 'User Created A New Reply';
$author = $event->reply->user;
$author->addPoints($amount, $message);
}
}
ReplyEvent
<?php
namespace App\Events;
use App\Models\Reply as Replyers;
use Illuminate\Queue\SerializesModels;
class ReplyWasCreated
{
use SerializesModels;
public $reply;
public function __construct(Replyers $reply)
{
$this->reply = $reply;
}
}
livewire reply componet
use Livewire\Component;
use App\Models\Reply as Replys;
class Reply extends Component
{
public $thread;
public $username;
public $reply_text;
public $replyCommentId = NULL;
protected $rules = [
'reply_text' => 'required'
];
public function mount(Thread $thread)
{
$this->thread = $thread;
}
public function render()
{
$replys = Replys::whereNull('parent_id')
->with('replies')
->with('user')
->where('thread_id', $this->thread->id)->paginate()->withQueryString();
return view('livewire.thread.reply',[
'replys' => $replys,
]);
}
public function save_reply()
{
$this->validate();
$replyevent = Replys::create([
'thread_id' => $this->thread->id,
'user_id' => auth()->user()->id,
'reply_text' => $this->reply_text,
'parent_id' => $this->replyCommentId
]);
event(new ReplyWasCreated($replyevent));
// $this->username = '';
$this->reply_text = '';
$this->replyCommentId = NULL;
}
public function deleteReply($id)
{
$reply = Replys::FindOrFail($id);
$reply->delete();
}
public function replys($replyId)
{
$this->replyCommentId = $replyId;
}
}
To get the id of a model, you simply access its id property. There is no id() method.
$currentPoints = Point::where('pointable_id', $pointable->id)
I don't understand this mistake, can someone help me?
I am taking a course on ApiRestfull and the code works for the teacher but I can't get it to work for me
I am using laravel 5.8*
The error he shows me is this: Error:
Argument 1 passed to App\Http\Controllers\ApiController::showAll() must be an instance of Illuminate\Database\Eloquent\Collection, instance of Illuminate\Support\Collection given, called in C:\laragon\www\udemy-apirestfull\app\Http\Controllers\Buyer\BuyerProductController.php on line 23
BuyerProductController.php:
<?php
namespace App\Http\Controllers\Buyer;
use App\Buyer;
use Illuminate\Http\Request;
use App\Http\Controllers\ApiController;
class BuyerProductController extends ApiController
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Buyer $buyer)
{
$products = $buyer->transactions()->with('product')
->get()
->pluck('product');
return $this->showAll($products);
}
}
ApiController:
<?php
namespace App\Http\Controllers;
use App\Traits\ApiResponser;
use Illuminate\Http\Request;
class ApiController extends Controller
{
use ApiResponser;
}
ApiResponser:
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
trait ApiResponser
{
private function successResponse($data, $code)
{
return response()->json($data, $code);
}
protected function errorResponse($message, $code)
{
return response()->json(['error' => $message, 'code' => $code], $code);
}
protected function showAll(Collection $collection, $code = 200)
{
return $this->successResponse(['data' => $collection], $code);
}
protected function showOne(Model $instance, $code = 200)
{
return $this->successResponse(['data' => $instance], $code);
}
}
Buyer model:
<?php
namespace App;
use App\Transaction;
use App\Scopes\BuyerScope;
class Buyer extends User
{
protected static function boot()
{
parent::boot();
static::addGlobalScope(new BuyerScope);
}
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}
Product Model:
<?php
namespace App;
use App\Seller;
use App\Category;
use App\Transaction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model
{
use SoftDeletes;
const PRODUCTO_DISPONIBLE = 'disponible';
const PRODUCTO_NO_DISPONIBLE = 'no disponible';
protected $dates = ['deleted_at'];
protected $fillable = [
'name',
'description',
'quantity',
'status',
'image',
'seller_id',
];
public function estaDisponible()
{
return $this->status == Product::PRODUCTO_DISPONIBLE;
}
public function seller()
{
return $this->belongsTo(Seller::class);
}
public function transactions()
{
return $this->hasMany(Transaction::class);
}
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
Transaction Model:
<?php
namespace App;
use App\Buyer;
use App\Product;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Transaction extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $fillable = [
'quantity',
'buyer_id',
'product_id',
];
public function buyer()
{
return $this->belongsTo(Buyer::class);
}
public function product()
{
return $this->belongsTo(Product::class);
}
}
Illuminate\Database\Eloquent\Collection extends Illuminate\Support\Collection
So if not mandatory, you can change the signature of showAll method to accept Illuminate\Support\Collection as a parameter
There will be no error if the parameter supplied will be an instance of Illuminate\Database\Eloquent\Collection
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection; //Changed here
trait ApiResponser
{
private function successResponse($data, $code)
{
return response()->json($data, $code);
}
protected function errorResponse($message, $code)
{
return response()->json(['error' => $message, 'code' => $code], $code);
}
protected function showAll(Collection $collection, $code = 200)
{
return $this->successResponse(['data' => $collection], $code);
}
protected function showOne(Model $instance, $code = 200)
{
return $this->successResponse(['data' => $instance], $code);
}
}
hi i have this relationships with these 3 models
Customers
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Customers extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'contr_nom',
'contr_cog',
'benef_nom',
'benef_cog',
'email',
'polizza',
'targa',
'iban',
'int_iban',
'cliente',
];
public function claims()
{
return $this->hasMany(Claims::class);
}
public function refunds()
{
return $this->hasManyThrough(Refunds::class, Claims::class);
}
}
Claims
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Claims extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'dossier',
'date_cla',
];
public function refunds()
{
return $this->hasMany(Refunds::class);
}
public function customers()
{
return $this->belongsTo(Customers::class,'customers_id');
}
}
and Refunds
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Refunds extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'date_ref',
'status_ref',
'disactive',
];
public function services()
{
return $this->belongsToMany(Services::class)
->withPivot(['services_id','services_amount','services_status']);
}
public function claims()
{
return $this->belongsTo(Claims::class,'claims_id');
}
}
i have this in the controller (part of the code)
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))->get();
it works, i can get customers information (parent table) for each dossier ( i put in a datatables)
But i cannot insert another filter based on Refunds table.
I need to show only dossiers where
['status_ref', '>',4]
the problem is that status_ref is in Refunds table
i tried to do somthing like this but no works
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))->refunds()
->where('status_ref', '>',4)
->get();
I cannot understand why....
Thx
You have to use whereHas like:
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))
->whereHas('refunds', function (Builder $query) {
$query->where('status_ref', '>', 4);
})
->get();
Here, I have setuo CRUD table with laravel, vuetify and vue . I could successfull create and read data from the database. But, for some reason my update and delete are not working. I am getting error like:
{message: "Creating default object from empty value", exception: "ErrorException",…}
exception: "ErrorException"
file: "C:\WinNMP\WWW\chillibiz\app\Sys\Http\Controllers\StageController.php"
line: 53
message: "Creating default object from empty value"
trace: [{file: "C:\WinNMP\WWW\chillibiz\app\Sys\Http\Controllers\StageController.php", line: 53,…},…]
My code are here:
StageController.php
<?php
namespace App\Sys\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Sys\Model\Stage;
class StageController extends Controller
{
public function index(Request $request)
{
$per_page = $request->per_page ? $request->per_page : 5;
$sort_by = $request->sort_by;
$order_by = $request->order_by;
return response()->json(['stages' => Stage::orderBy($sort_by, $order_by)->paginate($per_page)],200);
}
public function store(Request $request)
{
$uuid = Str::uuid()->toString();
$stage= Stage::create([
'id' => $uuid,
'code' =>$request->code,
'name' =>$request->name,
'description' =>$request->description,
]);
return response()->json(['stage'=>$stage],200);
}
public function show($id)
{
$stages = Stage::where('code','LIKE', "%$id%")->orWhere('name','LIKE', "%$id%")->orWhere('description', 'LIKE', "%$id%")->paginate();
return response()->json(['stages' => $stages],200);
}
public function update(Request $request, $id)
{
$stage = Stage::find($id);
$stage->code = $request->code; //line 53
$stage->name = $request->name;
$stage->description = $request->description;
$stage->save();
return response()->json(['stage'=>$stage], 200);
}
public function destroy($id)
{
$stage = Stage::where('id', $id)->delete();
return response()->json(['stage'=> $stage],200);
}
public function deleteAll(Request $request){
Stage::whereIn('id', $request->stages)->delete();
return response()->json(['message', 'Records Deleted Successfully'], 200);
}
}
Stage.php
<?php
namespace App\Sys\Model;
use Illuminate\Database\Eloquent\Model;
class Stage extends Model
{
protected $guarded = [];
}
I just found they you are using uuid as id not increment. that why you get error like that:
to solve your problem you need to add the field to your model;
<?php
namespace App\Sys\Model;
use Illuminate\Database\Eloquent\Model;
class Stage extends Model
{
public $incrementing = false;
protected $keyType = 'string';
protected $guarded = [];
}
I hope this time you can solve your problem. happy coding.
Edit you can read docs for more info
I'm struggling to get my head around a Laravel hasManyThrough and League/Fractal Transformers.
I have three tables:
Countries:
-id (int)
-other fields ...
Cities:
-id (int)
-country_id (int)
-other fields ...
Users
-id (int)
-city_id (string)
-some other ...
I'm trying to access Users relation from Country via Cities table relation, which is working using following Eloquent query:
$countryUsers = Country::with('users')->where('id', $id)->get();
But when I am trying to user $fractal to transform this relation, I'm getting Segmentation fault (core dumped) error.
In Country Controller I have:
class CountryController extends ApiController
{
protected $manager;
function __construct(Manager $manager) {
$this->manager = $manager;
}
public function show(CountryTransformer $countryTransformer, $id) {
$country = Country::find($id);
return $this->respondItem($country, $countryTransformer);
}
public function respondItem($item, $transformer)
{
$this->manager->setSerializer(new CustomArraySerializer());
$resource = new Item($item, $transformer);
$data = $this->manager->createData($resource)->toArray();
return $this->respond($data);
}
In my country model I have:
public function users() {
return $this->hasManyThrough('App\Models\User', 'App\Models\City');
}
public function cities() {
return $this->hasMany('App\Model\City');
}
City Model:
public function country() {
return $this->belongsTo('App\Models\Country');
}
User Model:
public function city()
{
return $this->belongsTo('App\Models\City');
}
and Fractal country transformer:
<?php namespace App\Transformers;
use App\Models\Country;
use League\Fractal\TransformerAbstract;
class CountryTransformer extends TransformerAbstract {
protected $defaultIncludes = [
'users'
];
public function transform(Country $country)
{
return [
'id' => $country->id,
'name' => $country->name,
'code' => $country->code,
'time_zone' => $country->time_zone,
'active' => $country->active,
'status' => $country->status,
'params' => $country->params
];
}
public function includeUsers(Country $country)
{
$users = $country->users;
if ($users) {
return $this->collection($users, new UserTransformer());
}
}
}
If anyone can point me in the right direction I'd really appreciate it. Thanks.