21-11-2025

This commit is contained in:
Kevin Adametz 2025-11-21 18:21:23 +01:00
parent fa2ebd457d
commit 07959c0ba2
113 changed files with 4730 additions and 898 deletions

10
app/Models/Attribute.php Normal file
View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Attribute extends Model
{
//
}

View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AttributeValue extends Model
{
//
}

33
app/Models/Brand.php Normal file
View file

@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Brand extends Model
{
use HasFactory;
protected $fillable = [
'partner_id',
'name',
'slug',
'description',
'logo_url',
'is_active',
];
protected $casts = [
'is_active' => 'boolean',
];
/**
* Eine Brand gehört zu einem Partner (Manufacturer)
*/
public function partner(): BelongsTo
{
return $this->belongsTo(Partner::class);
}
}

10
app/Models/Category.php Normal file
View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
//
}

10
app/Models/Collection.php Normal file
View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Collection extends Model
{
//
}

36
app/Models/Hub.php Normal file
View file

@ -0,0 +1,36 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Hub extends Model
{
use HasFactory;
protected $fillable = [
'name',
'slug',
'keyvisual_url',
'emblem_url',
'is_active',
];
/**
* Ein Hub besteht aus vielen Location-Einträgen (PLZs).
*/
public function locations(): HasMany
{
return $this->hasMany(HubLocation::class);
}
/**
* Ein Hub hat viele Partner (Händler, Makler).
*/
public function partners(): HasMany
{
return $this->hasMany(Partner::class);
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class HubLocation extends Model
{
use HasFactory;
protected $fillable = [
'hub_id',
'city_name',
'zip_code',
];
/**
* Dieser Location-Eintrag gehört zu einem Hub.
*/
public function hub(): BelongsTo
{
return $this->belongsTo(Hub::class);
}
}

58
app/Models/Partner.php Normal file
View file

@ -0,0 +1,58 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Partner extends Model
{
use HasFactory;
protected $fillable = [
'company_name',
'slug',
'type',
'hub_id',
'description',
'logo_url',
'is_active',
'setup_completed',
'setup_completed_at',
'delivery_radius_km',
'assembly_radius_km',
'provision_fixed_amount',
'provision_rate_percentage',
];
protected $casts = [
'is_active' => 'boolean',
'setup_completed' => 'boolean',
'setup_completed_at' => 'datetime',
];
/**
* Ein Partner (Händler/Makler) kann einem Hub zugeordnet sein.
* Ein Hersteller ist evtl. "global" (hub_id = null).
*/
public function hub(): BelongsTo
{
return $this->belongsTo(Hub::class);
}
/**
* Ein Partner (Firma) kann mehrere User-Logins haben.
*/
public function users(): HasMany
{
return $this->hasMany(User::class);
}
// TODO: Später die Beziehung zu Products hinzufügen
// public function products(): HasMany
// {
// return $this->hasMany(Product::class);
// }
}

View file

@ -0,0 +1,144 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;
use Spatie\Permission\Models\Role;
class PartnerInvitation extends Model
{
use HasFactory;
protected $fillable = [
'company_name',
'contact_first_name',
'contact_last_name',
'role_id',
'email',
'token',
'status',
'expires_at',
'invited_by',
'partner_id',
'accepted_at',
];
protected $casts = [
'expires_at' => 'datetime',
'accepted_at' => 'datetime',
];
/**
* Get the full contact name
*/
public function getContactFullNameAttribute(): ?string
{
$parts = array_filter([
$this->contact_first_name,
$this->contact_last_name,
]);
return !empty($parts) ? implode(' ', $parts) : null;
}
/**
* Generate a unique invitation token
*/
public static function generateToken(): string
{
do {
$token = Str::random(64);
} while (self::where('token', $token)->exists());
return $token;
}
/**
* Check if invitation is still valid
*/
public function isValid(): bool
{
return $this->status === 'pending' && $this->expires_at->isFuture();
}
/**
* Check if invitation is expired
*/
public function isExpired(): bool
{
return $this->expires_at->isPast() && $this->status === 'pending';
}
/**
* Mark invitation as expired
*/
public function markAsExpired(): void
{
$this->update(['status' => 'expired']);
}
/**
* Accept the invitation
*/
public function accept(Partner $partner): void
{
$this->update([
'status' => 'accepted',
'accepted_at' => now(),
'partner_id' => $partner->id,
]);
}
public function markAsAccepted(Partner $partner): void
{
$this->update([
'status' => 'accepted',
'accepted_at' => now(),
'partner_id' => $partner->id,
]);
}
/**
* Role assigned to the invitation
*/
public function role(): BelongsTo
{
return $this->belongsTo(Role::class);
}
/**
* User who sent the invitation
*/
public function invitedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'invited_by');
}
/**
* Partner created from this invitation
*/
public function partner(): BelongsTo
{
return $this->belongsTo(Partner::class);
}
/**
* Scope to get pending invitations
*/
public function scopePending($query)
{
return $query->where('status', 'pending')
->where('expires_at', '>', now());
}
/**
* Scope to get expired invitations
*/
public function scopeExpired($query)
{
return $query->where('status', 'pending')
->where('expires_at', '<=', now());
}
}

View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ProductVariant extends Model
{
//
}

View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ShippingClass extends Model
{
//
}

10
app/Models/Tag.php Normal file
View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
//
}

10
app/Models/TaxRate.php Normal file
View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TaxRate extends Model
{
//
}

View file

@ -10,6 +10,7 @@ use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class User extends Authenticatable
{
@ -22,9 +23,11 @@ class User extends Authenticatable
* @var list<string>
*/
protected $fillable = [
'partner_id',
'name',
'email',
'password',
'email_verified_at',
];
/**
@ -50,6 +53,10 @@ class User extends Authenticatable
];
}
public function partner(): BelongsTo
{
return $this->belongsTo(Partner::class);
}
/**
* Get the user's initials
*/
@ -57,7 +64,7 @@ class User extends Authenticatable
{
return Str::of($this->name)
->explode(' ')
->map(fn (string $name) => Str::of($name)->substr(0, 1))
->map(fn(string $name) => Str::of($name)->substr(0, 1))
->implode('');
}
}