In my laravel applicaion I have order and status in many to many relationship. I want to fetch the orders based on the letest status set to the pivot order_status table. I also want to filter the data according to the letest status.
Here is my order model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Staudenmeir\EloquentEagerLimit\HasEagerLimit;
class Order extends Model
{
use HasFactory, HasEagerLimit;
protected $fillable = [
'status'
];
public static function boot(): void
{
parent::boot();
static::creating(function ($order) {
$order->order_id = 'ET-ORD-' . static::generateNextOrderNumber();
});
}
private static function generateNextOrderNumber(): string
{
$lastOrder = static::orderByDesc('id')->first();
if ($lastOrder) {
$lastOrderNumber = (int) substr($lastOrder->order_id, -4);
return str_pad($lastOrderNumber + 1, 4, '0', STR_PAD_LEFT);
}
return '1000';
}
public function createdBy()
{
return $this->belongsTo(User::class, 'created_by');
}
public function product(): HasMany
{
return $this->hasMany(Product::class);
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
public function orderable()
{
return $this->morphTo();
}
public function image()
{
return $this->morphMany(Image::class, 'imageable');
}
public function statuses(): BelongsToMany
{
return $this->belongsToMany(Status::class)->withTimestamps();
}
public function latestStatuses()
{
return $this->belongsToMany(Status::class)
->orderByPivot('created_at', 'desc')->limit(1);
}
protected function deliveryChannel(): Attribute
{
return Attribute::make(
get: function ($value) {
$deliveryChannel = DeliveryChannel::find($value);
return [
'value' => $value,
'name' => $deliveryChannel->name,
];
},
);
}
}
I have tried the query as below
public function getMarketplaceOrders($userID, Request $request): ResourceCollection
{
$user = User::find($userID);
$search = $request->input('search', '');
$status = $request->input('status') ? array_map('intval', explode(',', $request->input('status'))) : [];
$pageSize = OrderController::PAGESIZE;
if ($user->hasPermissionTo("VIEW_ALL_ORDERS")) {
$query = Order::whereHasMorph('orderable', Marketplace::class)
->with(['latestStatuses' => function ($query) use ($status) {
if (!empty($status)) {
return $query->whereIn('status_id', $status);
}
return $query;
},
'orderable' => function ($query) {
$query->select('id', 'name');
},
'createdBy' => function ($query) {
$query->select('id', 'firstname', 'lastname');
}])->latest('id');
} else {
$query = Order::whereHasMorph('orderable', [Marketplace::class], function (Builder $query) use ($userID) {
$query->whereHas('users', function ($q) use ($userID) {
$q->where("marketplace_user.user_id", $userID);
});
})
->with(['latestStatuses' => function ($query) use ($status) {
if (!empty($status)) {
return $query->whereIn('status_id', $status);
}
return $query;
}, 'orderable' => function ($query) {
$query->select('id', 'name');
},
'createdBy' => function ($query) {
$query->select('id', 'firstname', 'lastname');
}])->latest('id');
}
if (!empty($status)) {
$query->whereHas('latestStatuses', function ($query) use ($status) {
$query->whereIn('status_id', $status);
});
}
if (!empty($search)){
$query->where('id', $search);
}
$orders = $query->paginate($pageSize);
return OrdersResource::collection($orders);
}
This is working correctly for the fetching the letest orders but this is not working for filtering the orders. When I filter it gives the previous status for the orders and only the last 13 orders are fetching as the pagesize is 13.