WIP: Sicherheitsnetz vor Phase-1-R\u00fcckbau
Enth\u00e4lt gemischt: Laravel-10-Upgrade + Phase 1 (Contacts-Modul, Duplicats-Commands, Soft-Delete+Merge-Fields) + Phase 2 Code-Umstellungen (inquiry_id, $table='contacts'/'inquiries') + Offers-Modul (Migrationen, Models, offer_id in Booking, offer-Disk in filesystems.php). Phase 2 + Offers werden im folgenden Commit nach dev/backups/phase2-offers-2026-04-17/ verschoben, damit der Workspace auf Phase-1-only (= Test-System-Stand) reduziert ist und direkt auf Live deploybar wird. Tarball-Backup zus\u00e4tzlich unter: ../backups-safety/workspace-pre-phase1-rollback-2026-04-17.tar.gz Made-with: Cursor
This commit is contained in:
parent
389d5d1820
commit
e3dc1afd8e
165 changed files with 21914 additions and 3516 deletions
|
|
@ -1,56 +1,132 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Created by Reliese Model.
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\User;
|
||||
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\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class Offer
|
||||
* Angebot (Modul 6).
|
||||
*
|
||||
* Ein Offer ist der logische Angebots-Kopf (Angebotsnummer, Status,
|
||||
* Referenzen). Die Inhalte (Texte, Positionen, PDF) liegen versionsweise
|
||||
* in {@see OfferVersion}. Nach dem ersten Versand ist jede Änderung
|
||||
* eine neue Version (Entscheidung 17.1 Entwicklungsplan).
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $lead_id
|
||||
* @property float $total
|
||||
* @property boolean $binary_data
|
||||
* @property string $offer_number
|
||||
* @property int $contact_id
|
||||
* @property int|null $inquiry_id
|
||||
* @property int|null $booking_id
|
||||
* @property string $status
|
||||
* @property int|null $current_version_id
|
||||
* @property int $created_by
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property Lead $lead
|
||||
* @package App\Models
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer whereBinaryData($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer whereLeadId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer whereTotal($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Offer whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property Carbon|null $deleted_at
|
||||
* @property-read Contact $contact
|
||||
* @property-read Lead|null $inquiry
|
||||
* @property-read Booking|null $booking
|
||||
* @property-read OfferVersion|null $currentVersion
|
||||
* @property-read Collection|OfferVersion[] $versions
|
||||
* @property-read Collection|OfferAccessToken[] $accessTokens
|
||||
* @property-read User $creator
|
||||
*/
|
||||
class Offer extends Model
|
||||
{
|
||||
protected $connection = 'mysql';
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $table = 'offer';
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
public const STATUS_SENT = 'sent';
|
||||
public const STATUS_ACCEPTED = 'accepted';
|
||||
public const STATUS_DECLINED = 'declined';
|
||||
public const STATUS_EXPIRED = 'expired';
|
||||
public const STATUS_WITHDRAWN = 'withdrawn';
|
||||
|
||||
protected $casts = [
|
||||
'lead_id' => 'int',
|
||||
'total' => 'float',
|
||||
'binary_data' => 'boolean'
|
||||
];
|
||||
public const STATUSES = [
|
||||
self::STATUS_DRAFT,
|
||||
self::STATUS_SENT,
|
||||
self::STATUS_ACCEPTED,
|
||||
self::STATUS_DECLINED,
|
||||
self::STATUS_EXPIRED,
|
||||
self::STATUS_WITHDRAWN,
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'lead_id',
|
||||
'total',
|
||||
'binary_data'
|
||||
];
|
||||
protected $table = 'offers';
|
||||
|
||||
public function lead()
|
||||
{
|
||||
return $this->belongsTo(Lead::class);
|
||||
}
|
||||
protected $fillable = [
|
||||
'offer_number',
|
||||
'contact_id',
|
||||
'inquiry_id',
|
||||
'booking_id',
|
||||
'status',
|
||||
'current_version_id',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'contact_id' => 'int',
|
||||
'inquiry_id' => 'int',
|
||||
'booking_id' => 'int',
|
||||
'current_version_id' => 'int',
|
||||
'created_by' => 'int',
|
||||
];
|
||||
|
||||
public function contact(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Contact::class);
|
||||
}
|
||||
|
||||
public function inquiry(): BelongsTo
|
||||
{
|
||||
// Nach Modul 3 Phase 2: `Lead`-Model bildet die `inquiries`-Tabelle ab
|
||||
return $this->belongsTo(Lead::class, 'inquiry_id');
|
||||
}
|
||||
|
||||
public function booking(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Booking::class);
|
||||
}
|
||||
|
||||
public function currentVersion(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(OfferVersion::class, 'current_version_id');
|
||||
}
|
||||
|
||||
public function versions(): HasMany
|
||||
{
|
||||
return $this->hasMany(OfferVersion::class)->orderBy('version_no');
|
||||
}
|
||||
|
||||
public function accessTokens(): HasMany
|
||||
{
|
||||
return $this->hasMany(OfferAccessToken::class);
|
||||
}
|
||||
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function scopeStatus(Builder $q, string $status): Builder
|
||||
{
|
||||
return $q->where('status', $status);
|
||||
}
|
||||
|
||||
public function scopeOpen(Builder $q): Builder
|
||||
{
|
||||
return $q->whereIn('status', [self::STATUS_DRAFT, self::STATUS_SENT]);
|
||||
}
|
||||
|
||||
public function isEditable(): bool
|
||||
{
|
||||
return in_array($this->status, [self::STATUS_DRAFT, self::STATUS_SENT], true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue