164 lines
5 KiB
PHP
164 lines
5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Models\Sym\TravelCountry;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
|
|
/**
|
|
* Kontakt-Modell — saubere Neuimplementierung auf Basis der customer-Tabelle.
|
|
*
|
|
* Unterschiede zum alten Customer-Modell:
|
|
* - Global Scope schließt zusammengeführte Duplikate (merged_into_id IS NOT NULL) aus
|
|
* - merged_into_id + merged_at in $fillable
|
|
* - mergedInto() / mergedContacts() Beziehungen
|
|
*
|
|
* Tabellen-Name: 'customer' (wird in Phase 2 in 'contacts' umbenannt).
|
|
*
|
|
* @property int $id
|
|
* @property int|null $salutation_id
|
|
* @property string|null $title
|
|
* @property string|null $name
|
|
* @property string|null $firstname
|
|
* @property Carbon|null $birthdate
|
|
* @property string|null $company
|
|
* @property string|null $street
|
|
* @property string|null $zip
|
|
* @property string|null $city
|
|
* @property string|null $email
|
|
* @property string|null $phone
|
|
* @property string|null $phonebusiness
|
|
* @property string|null $phonemobile
|
|
* @property string|null $fax
|
|
* @property int|null $merged_into_id
|
|
* @property Carbon|null $merged_at
|
|
* @property Carbon $created_at
|
|
* @property Carbon $updated_at
|
|
* @property-read Contact|null $mergedInto
|
|
* @property-read Collection|Contact[] $mergedContacts
|
|
* @property-read Collection|Lead[] $leads
|
|
* @property-read Collection|Booking[] $bookings
|
|
*/
|
|
class Contact extends Model
|
|
{
|
|
use HasFactory, SoftDeletes;
|
|
|
|
protected $connection = 'mysql';
|
|
|
|
protected $table = 'customer';
|
|
|
|
protected $casts = [
|
|
'salutation_id' => 'int',
|
|
'credit_card_type_id' => 'int',
|
|
'country_id' => 'int',
|
|
'merged_into_id' => 'int',
|
|
'birthdate' => 'datetime',
|
|
'credit_card_expiration_date' => 'datetime',
|
|
'merged_at' => 'datetime',
|
|
];
|
|
|
|
protected $fillable = [
|
|
'salutation_id',
|
|
'title',
|
|
'name',
|
|
'firstname',
|
|
'birthdate',
|
|
'company',
|
|
'street',
|
|
'zip',
|
|
'city',
|
|
'email',
|
|
'phone',
|
|
'phonebusiness',
|
|
'phonemobile',
|
|
'fax',
|
|
'bank',
|
|
'bank_code',
|
|
'bank_account_number',
|
|
'credit_card_type_id',
|
|
'credit_card_number',
|
|
'credit_card_expiration_date',
|
|
'participants_remarks',
|
|
'miscellaneous_remarks',
|
|
'country_id',
|
|
'merged_into_id',
|
|
'merged_at',
|
|
];
|
|
|
|
/**
|
|
* Globaler Scope: zusammengeführte Duplikate werden standardmäßig ausgeblendet.
|
|
* Für Zugriff auf alle inkl. Duplikate: Contact::withoutGlobalScope('not_merged')
|
|
*/
|
|
protected static function booted(): void
|
|
{
|
|
static::addGlobalScope('not_merged', function (Builder $query) {
|
|
$query->whereNull('merged_into_id');
|
|
});
|
|
}
|
|
|
|
// ── Beziehungen ──────────────────────────────────────────────────────────
|
|
|
|
public function mergedInto(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
{
|
|
return $this->belongsTo(Contact::class, 'merged_into_id')
|
|
->withoutGlobalScope('not_merged');
|
|
}
|
|
|
|
public function mergedContacts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
|
{
|
|
return $this->hasMany(Contact::class, 'merged_into_id')
|
|
->withoutGlobalScope('not_merged');
|
|
}
|
|
|
|
public function leads(): \Illuminate\Database\Eloquent\Relations\HasMany
|
|
{
|
|
return $this->hasMany(Lead::class, 'customer_id')->orderByDesc('created_at');
|
|
}
|
|
|
|
public function bookings(): \Illuminate\Database\Eloquent\Relations\HasMany
|
|
{
|
|
return $this->hasMany(Booking::class, 'customer_id')->orderByDesc('created_at');
|
|
}
|
|
|
|
public function salutation(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
{
|
|
return $this->belongsTo(Salutation::class);
|
|
}
|
|
|
|
public function travel_country(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
{
|
|
return $this->belongsTo(TravelCountry::class, 'country_id');
|
|
}
|
|
|
|
// ── Hilfsmethoden ────────────────────────────────────────────────────────
|
|
|
|
public function fullName(): string
|
|
{
|
|
if ($this->firstname) {
|
|
return $this->firstname . ' ' . $this->name;
|
|
}
|
|
return (string) $this->name;
|
|
}
|
|
|
|
public function isMerged(): bool
|
|
{
|
|
return $this->merged_into_id !== null;
|
|
}
|
|
|
|
public static function getCountriesArray(): \Illuminate\Support\Collection
|
|
{
|
|
return TravelCountry::where('is_customer_country', 1)->get()->pluck('name', 'id');
|
|
}
|
|
|
|
public static $salutationType = [
|
|
1 => 'Herr',
|
|
2 => 'Frau',
|
|
3 => 'Divers/keine Anrede',
|
|
4 => 'Firma',
|
|
];
|
|
}
|