170 lines
5.4 KiB
Diff
170 lines
5.4 KiB
Diff
diff --git a/app/Models/Contact.php b/app/Models/Contact.php
|
|
new file mode 100644
|
|
index 0000000..6d941e8
|
|
--- /dev/null
|
|
+++ b/app/Models/Contact.php
|
|
@@ -0,0 +1,164 @@
|
|
+<?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',
|
|
+ ];
|
|
+}
|