payment_purpose !== null) { return $this->payment_purpose; } $subject = $this->type === InvoiceType::INVOICE_TYPE_PARTICIPATION_REFUND ? 'Beitragserstattung' : 'Auslagenerstattung'; return $subject . ' Belegnummer ' . $this->invoice_number; } /** * Wofür der Beleg steht -- der "Zahlungsgrund" der Beleglisten und der "Zweck" der EüR-Anlage. * * Erfasst wird er beim Anlegen und steht danach in der eigenen Spalte: eine Angabe, keine Ableitung. * Nur so lässt er sich korrigieren, ohne dass ihn der nächste Vorgang wieder überschreibt. * * Bestandsbelege haben die Spalte leer -- für sie wird weiter abgeleitet, bei Fahrtkosten aus * Reisegrund und `contact_name`, weil es die Frage "wer ist gefahren" damals nicht gab. Bleibt auch * dabei nichts übrig, bleibt der Text leer; ein "--" würde in einer Belegliste nur Platz kosten. */ public function purposeText() : string { if (trim((string) $this->purpose) !== '') { return $this->purpose; } return self::joinPurposeParts( $this->type === InvoiceType::INVOICE_TYPE_TRAVELLING ? [$this->travelReasonText(), $this->contact_name] : [$this->type_other] ); } /** * Der Reisegrund als lesbarer Text. * * Der Name des gewählten Grundes -- oder der Wert selbst, wenn er zu keinem passt. Der ist dann der * Freitext von "Anderer Grund" oder stammt aus der Zeit vor der Auswahl. */ public function travelReasonText() : string { return TravelReason::text($this->travel_reason); } /** * Setzt einen Zahlungsgrund aus seinen Teilen zusammen: leere fallen weg, damit kein " — " führt * oder hängt. * * @param array $parts */ public static function joinPurposeParts(array $parts) : string { $parts = array_map(fn ($part) => trim((string) $part), $parts); return implode(' — ', array_filter($parts, fn ($part) => $part !== '')); } public function costUnit() : BelongsTo{ return $this->belongsTo(CostUnit::class); } public function status() : BelongsTo { return $this->belongsTo(InvoiceStatus::class, 'status')->first(); } public function invoiceType() : InvoiceType { return $this->belongsTo(InvoiceType::class, 'type', 'slug')->first(); } public function approvedBy() : ?User { return $this->belongsTo(User::class, 'approved_by')->first(); } }