126 lines
3.5 KiB
PHP
126 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\User;
|
|
use Carbon\Carbon;
|
|
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;
|
|
|
|
/**
|
|
* Version eines Angebots (Modul 6).
|
|
*
|
|
* Jede versendete Fassung wird hier festgehalten — Texte, Positionen
|
|
* und PDF bleiben damit unveränderlich, sobald ein Kunde sie per
|
|
* Freigabe-Link einsehen kann. Neue Änderungen nach dem Versand
|
|
* erzeugen eine neue Version (version_no = max+1, status = draft).
|
|
*
|
|
* @property int $id
|
|
* @property int $offer_id
|
|
* @property int $version_no
|
|
* @property string $status
|
|
* @property Carbon|null $valid_until
|
|
* @property float $total_price
|
|
* @property string|null $headline
|
|
* @property string|null $intro_text
|
|
* @property string|null $itinerary_text
|
|
* @property string|null $closing_text
|
|
* @property int|null $template_id
|
|
* @property string|null $pdf_path
|
|
* @property bool $pdf_archived
|
|
* @property Carbon|null $sent_at
|
|
* @property Carbon|null $accepted_at
|
|
* @property string|null $accepted_via
|
|
* @property array|null $template_document_ids
|
|
* @property int $created_by
|
|
* @property Carbon $created_at
|
|
* @property Carbon $updated_at
|
|
* @property-read Offer $offer
|
|
* @property-read OfferTemplate|null $template
|
|
* @property-read Collection|OfferItem[] $items
|
|
* @property-read Collection|OfferFile[] $files
|
|
* @property-read User $creator
|
|
*/
|
|
class OfferVersion extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
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_SUPERSEDED = 'superseded';
|
|
|
|
public const ACCEPTED_VIA_LINK = 'customer_link';
|
|
public const ACCEPTED_VIA_ADMIN = 'admin';
|
|
public const ACCEPTED_VIA_MAIL = 'email';
|
|
|
|
protected $table = 'offer_versions';
|
|
|
|
protected $fillable = [
|
|
'offer_id',
|
|
'version_no',
|
|
'status',
|
|
'valid_until',
|
|
'total_price',
|
|
'headline',
|
|
'intro_text',
|
|
'itinerary_text',
|
|
'closing_text',
|
|
'template_id',
|
|
'pdf_path',
|
|
'pdf_archived',
|
|
'sent_at',
|
|
'accepted_at',
|
|
'accepted_via',
|
|
'template_document_ids',
|
|
'created_by',
|
|
];
|
|
|
|
protected $casts = [
|
|
'offer_id' => 'int',
|
|
'version_no' => 'int',
|
|
'valid_until' => 'date',
|
|
'total_price' => 'decimal:2',
|
|
'template_id' => 'int',
|
|
'pdf_archived' => 'bool',
|
|
'sent_at' => 'datetime',
|
|
'accepted_at' => 'datetime',
|
|
'template_document_ids' => 'array',
|
|
'created_by' => 'int',
|
|
];
|
|
|
|
public function offer(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Offer::class);
|
|
}
|
|
|
|
public function template(): BelongsTo
|
|
{
|
|
return $this->belongsTo(OfferTemplate::class, 'template_id');
|
|
}
|
|
|
|
public function items(): HasMany
|
|
{
|
|
return $this->hasMany(OfferItem::class)->orderBy('position');
|
|
}
|
|
|
|
public function files(): HasMany
|
|
{
|
|
return $this->hasMany(OfferFile::class);
|
|
}
|
|
|
|
public function creator(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'created_by');
|
|
}
|
|
|
|
public function isEditable(): bool
|
|
{
|
|
return $this->status === self::STATUS_DRAFT;
|
|
}
|
|
}
|