أُنشئ من Tokal/Test
backend: align API/models with current PostgreSQL schema
فشلت بعض الفحوصات
Deploy Backend / deploy (push) Has been cancelled
فشلت بعض الفحوصات
Deploy Backend / deploy (push) Has been cancelled
هذا الالتزام موجود في:
17
app/Models/Amenity.php
Normal file
17
app/Models/Amenity.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Amenity extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
}
|
||||
30
app/Models/Offer.php
Normal file
30
app/Models/Offer.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Offer extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'venue_id',
|
||||
'title',
|
||||
'description',
|
||||
'image_url',
|
||||
'start_at',
|
||||
'end_at',
|
||||
'is_active',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'start_at' => 'datetime',
|
||||
'end_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@@ -4,21 +4,43 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ReservationStatusHistory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
protected static ?string $resolvedTable = null;
|
||||
|
||||
protected $fillable = [
|
||||
'reservation_id',
|
||||
'old_status',
|
||||
'new_status',
|
||||
'changed_by_user_id',
|
||||
'note',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
$this->table = self::tableName();
|
||||
}
|
||||
|
||||
public static function tableName(): string
|
||||
{
|
||||
if (self::$resolvedTable !== null) {
|
||||
return self::$resolvedTable;
|
||||
}
|
||||
|
||||
self::$resolvedTable = Schema::hasTable('reservation_status_histories')
|
||||
? 'reservation_status_histories'
|
||||
: 'reservation_status_history';
|
||||
|
||||
return self::$resolvedTable;
|
||||
}
|
||||
|
||||
public function reservation()
|
||||
{
|
||||
return $this->belongsTo(Reservation::class);
|
||||
|
||||
@@ -4,15 +4,19 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ReservationTableAssignment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
protected static ?string $resolvedTable = null;
|
||||
protected static ?string $resolvedTableForeignKey = null;
|
||||
|
||||
protected $fillable = [
|
||||
'reservation_id',
|
||||
'table_id',
|
||||
'venue_table_id',
|
||||
'assigned_at',
|
||||
];
|
||||
@@ -21,6 +25,49 @@ class ReservationTableAssignment extends Model
|
||||
'assigned_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
$this->table = self::tableName();
|
||||
}
|
||||
|
||||
public static function tableName(): string
|
||||
{
|
||||
if (self::$resolvedTable !== null) {
|
||||
return self::$resolvedTable;
|
||||
}
|
||||
|
||||
self::$resolvedTable = Schema::hasTable('reservation_table_assignments')
|
||||
? 'reservation_table_assignments'
|
||||
: 'reservation_tables';
|
||||
|
||||
return self::$resolvedTable;
|
||||
}
|
||||
|
||||
public static function tableForeignKey(): string
|
||||
{
|
||||
if (self::$resolvedTableForeignKey !== null) {
|
||||
return self::$resolvedTableForeignKey;
|
||||
}
|
||||
|
||||
self::$resolvedTableForeignKey = Schema::hasColumn(self::tableName(), 'venue_table_id')
|
||||
? 'venue_table_id'
|
||||
: 'table_id';
|
||||
|
||||
return self::$resolvedTableForeignKey;
|
||||
}
|
||||
|
||||
public function setVenueTableIdAttribute($value): void
|
||||
{
|
||||
$this->attributes[self::tableForeignKey()] = $value;
|
||||
}
|
||||
|
||||
public function getVenueTableIdAttribute()
|
||||
{
|
||||
$column = self::tableForeignKey();
|
||||
return $this->attributes[$column] ?? null;
|
||||
}
|
||||
|
||||
public function reservation()
|
||||
{
|
||||
return $this->belongsTo(Reservation::class);
|
||||
@@ -28,6 +75,6 @@ class ReservationTableAssignment extends Model
|
||||
|
||||
public function table()
|
||||
{
|
||||
return $this->belongsTo(VenueTable::class, 'venue_table_id');
|
||||
return $this->belongsTo(VenueTable::class, self::tableForeignKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,15 @@ use App\Models\Reservation;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Models\Notification;
|
||||
use App\Models\UserFeedback;
|
||||
use App\Models\UserBlock;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
protected static ?bool $hasLegacyBlockColumns = null;
|
||||
protected static ?bool $hasUserBlocksTable = null;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@@ -86,14 +90,53 @@ class User extends Authenticatable
|
||||
|
||||
public function isBlocked(): bool
|
||||
{
|
||||
if ($this->blocked_permanent) {
|
||||
return true;
|
||||
if ($this->hasLegacyBlockColumns()) {
|
||||
if ($this->blocked_permanent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->blocked_until && Carbon::parse($this->blocked_until)->isFuture()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->blocked_until && Carbon::parse($this->blocked_until)->isFuture()) {
|
||||
return true;
|
||||
if (! $this->hasUserBlocksTable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return UserBlock::query()
|
||||
->where('user_id', $this->id)
|
||||
->where('is_active', true)
|
||||
->where(function ($q) {
|
||||
$q->whereNull('blocked_until')
|
||||
->orWhere('blocked_until', '>', now());
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
|
||||
private function hasLegacyBlockColumns(): bool
|
||||
{
|
||||
if (self::$hasLegacyBlockColumns !== null) {
|
||||
return self::$hasLegacyBlockColumns;
|
||||
}
|
||||
|
||||
self::$hasLegacyBlockColumns = Schema::hasColumn('users', 'blocked_until')
|
||||
&& Schema::hasColumn('users', 'blocked_permanent')
|
||||
&& Schema::hasColumn('users', 'strike_count');
|
||||
|
||||
return self::$hasLegacyBlockColumns;
|
||||
}
|
||||
|
||||
private function hasUserBlocksTable(): bool
|
||||
{
|
||||
if (self::$hasUserBlocksTable !== null) {
|
||||
return self::$hasUserBlocksTable;
|
||||
}
|
||||
|
||||
self::$hasUserBlocksTable = Schema::hasTable('user_blocks');
|
||||
|
||||
return self::$hasUserBlocksTable;
|
||||
}
|
||||
}
|
||||
|
||||
32
app/Models/UserBlock.php
Normal file
32
app/Models/UserBlock.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class UserBlock extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $table = 'user_blocks';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'level',
|
||||
'reason',
|
||||
'blocked_until',
|
||||
'created_by',
|
||||
'created_by_user_id',
|
||||
'trigger_venue_id',
|
||||
'is_active',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'blocked_until' => 'datetime',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
23
app/Models/UserStrike.php
Normal file
23
app/Models/UserStrike.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class UserStrike extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $table = 'user_strikes';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'reservation_id',
|
||||
'venue_id',
|
||||
'type',
|
||||
'created_at',
|
||||
];
|
||||
}
|
||||
@@ -8,6 +8,9 @@ use Illuminate\Support\Facades\Schema;
|
||||
use App\Models\Reservation;
|
||||
use App\Models\SeatingArea;
|
||||
use App\Models\VenueTable;
|
||||
use App\Models\Offer;
|
||||
use App\Models\VenueImage;
|
||||
use App\Models\Amenity;
|
||||
|
||||
class Venue extends Model
|
||||
{
|
||||
@@ -29,6 +32,7 @@ class Venue extends Model
|
||||
'amenities',
|
||||
'image_urls',
|
||||
'offers',
|
||||
'created_by_admin_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
@@ -80,4 +84,19 @@ class Venue extends Model
|
||||
{
|
||||
return $this->hasMany(VenueTable::class);
|
||||
}
|
||||
|
||||
public function images()
|
||||
{
|
||||
return $this->hasMany(VenueImage::class);
|
||||
}
|
||||
|
||||
public function offersRelation()
|
||||
{
|
||||
return $this->hasMany(Offer::class);
|
||||
}
|
||||
|
||||
public function amenitiesRelation()
|
||||
{
|
||||
return $this->belongsToMany(Amenity::class, 'venue_amenities', 'venue_id', 'amenity_id');
|
||||
}
|
||||
}
|
||||
|
||||
21
app/Models/VenueImage.php
Normal file
21
app/Models/VenueImage.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class VenueImage extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $table = 'venue_images';
|
||||
|
||||
protected $fillable = [
|
||||
'venue_id',
|
||||
'url',
|
||||
'sort_order',
|
||||
];
|
||||
}
|
||||
المرجع في مشكلة جديدة
حظر مستخدم