created_by = auth()->id()`. protected $fillable = [ 'order_number', 'supplier_id', 'company_id', 'purchase_date', 'notes', 'currency', ]; protected $casts = [ 'purchase_date' => 'date', ]; /** * FKs use `exists` so bad IDs from a request never persist. Every * write path already runs through the ValidatingTrait via SnipeModel; * a validation failure blocks the save() and surfaces the error to * the caller. */ public $rules = [ 'order_number' => 'nullable|string|max:255', 'supplier_id' => 'nullable|integer|exists:suppliers,id', 'company_id' => 'nullable|integer|exists:companies,id', 'purchase_date' => 'nullable|date', 'notes' => 'nullable|string|max:1000', 'currency' => 'nullable|string|max:10', ]; protected $injectUniqueIdentifier = true; public function orderItems(): HasMany { return $this->hasMany(OrderItem::class); } public function supplier(): BelongsTo { return $this->belongsTo(Supplier::class); } public function company(): BelongsTo { return $this->belongsTo(Company::class); } public function admin(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } /** * Currency to display for this order. Falls back to the system * default when the row's own `currency` column is null, so display * code doesn't have to reach for `$snipeSettings->default_currency` * itself. Returns null when neither is set (rare, but possible on * fresh installs with the default_currency setting unwritten). */ public function displayCurrency(): ?string { if ($this->currency !== null && $this->currency !== '') { return $this->currency; } $default = Setting::getSettings()?->default_currency; return $default ?: null; } }