86 lines
2.4 KiB
PHP
86 lines
2.4 KiB
PHP
<?php
|
||
|
||
namespace App\Models;
|
||
|
||
use Carbon\Carbon;
|
||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||
use Illuminate\Database\Eloquent\Model;
|
||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||
|
||
/**
|
||
* Position einer Angebotsversion (Modul 6).
|
||
*
|
||
* `travel_program_id` und `fewo_lodging_id` bleiben FK-frei, solange
|
||
* Modul 12 (v2-Reiseverwaltung) noch nicht nach Laravel migriert ist.
|
||
* `metadata` enthält einen Snapshot der Referenzdaten (Titel, Preis,
|
||
* Leistungen) — so bleiben Positionen lesbar, auch wenn das Original
|
||
* später gelöscht / migriert / umbenannt wird.
|
||
*
|
||
* @property int $id
|
||
* @property int $offer_version_id
|
||
* @property int $position
|
||
* @property string $type
|
||
* @property string $title
|
||
* @property string|null $description
|
||
* @property int $quantity
|
||
* @property float $price_per_unit
|
||
* @property float $total_price
|
||
* @property int|null $travel_program_id
|
||
* @property int|null $fewo_lodging_id
|
||
* @property array|null $metadata
|
||
* @property Carbon $created_at
|
||
* @property Carbon $updated_at
|
||
* @property-read OfferVersion $version
|
||
*/
|
||
class OfferItem extends Model
|
||
{
|
||
use HasFactory;
|
||
|
||
public const TYPE_TRAVEL = 'travel';
|
||
public const TYPE_SERVICE = 'service';
|
||
public const TYPE_OPTION = 'option';
|
||
public const TYPE_DISCOUNT = 'discount';
|
||
public const TYPE_INSURANCE = 'insurance';
|
||
public const TYPE_CUSTOM = 'custom';
|
||
|
||
protected $table = 'offer_items';
|
||
|
||
protected $fillable = [
|
||
'offer_version_id',
|
||
'position',
|
||
'type',
|
||
'title',
|
||
'description',
|
||
'quantity',
|
||
'price_per_unit',
|
||
'total_price',
|
||
'travel_program_id',
|
||
'fewo_lodging_id',
|
||
'metadata',
|
||
];
|
||
|
||
protected $casts = [
|
||
'offer_version_id' => 'int',
|
||
'position' => 'int',
|
||
'quantity' => 'int',
|
||
'price_per_unit' => 'decimal:2',
|
||
'total_price' => 'decimal:2',
|
||
'travel_program_id' => 'int',
|
||
'fewo_lodging_id' => 'int',
|
||
'metadata' => 'array',
|
||
];
|
||
|
||
public function version(): BelongsTo
|
||
{
|
||
return $this->belongsTo(OfferVersion::class, 'offer_version_id');
|
||
}
|
||
|
||
/**
|
||
* Aus Menge × Einzelpreis den Positions-Gesamtpreis berechnen
|
||
* (Rabatte negativ — gehört in den Service-Layer zur Summierung).
|
||
*/
|
||
public function calculateTotal(): float
|
||
{
|
||
return round($this->quantity * (float) $this->price_per_unit, 2);
|
||
}
|
||
}
|