pp-planer/app/Models/Song.php
Thorsten Bus a36841f920 feat(songs): add CTS song ID matching, info slide date filter, arrangement ordering, translation defaults
- Add cts_song_id column to songs and service_songs for CCLI-free matching fallback
- Filter information slides by uploaded_at <= service date (not shown before upload)
- New arrangements use song's default group ordering instead of cloning
- Auto-set use_translation=true when matched song has translation
- Update syncSongs/syncServiceAgendaSongs to store and use cts_song_id
- Add tests for CTS song ID fallback, upload date filtering, and translation defaults
2026-03-02 14:10:40 +01:00

71 lines
1.7 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Casts\Attribute;
class Song extends Model
{
use HasFactory;
use SoftDeletes;
protected $fillable = [
'ccli_id',
'cts_song_id',
'title',
'author',
'copyright_text',
'copyright_year',
'publisher',
'has_translation',
'last_used_at',
];
protected function casts(): array
{
return [
'has_translation' => 'boolean',
'last_used_at' => 'datetime',
];
}
public function groups(): HasMany
{
return $this->hasMany(SongGroup::class);
}
public function arrangements(): HasMany
{
return $this->hasMany(SongArrangement::class);
}
public function serviceSongs(): HasMany
{
return $this->hasMany(ServiceSong::class);
}
/**
* Letztes Service-Datum, in dem dieser Song verwendet wurde.
* Berechnet über die service_songs -> services Verknüpfung.
*/
public function lastUsedInService(): Attribute
{
return Attribute::get(function () {
$latestDate = $this->serviceSongs()
->join('services', 'services.id', '=', 'service_songs.service_id')
->max('services.date');
if ($latestDate === null) {
return null;
}
// SQLite gibt date-Spalten als 'YYYY-MM-DD 00:00:00' zurück
return substr((string) $latestDate, 0, 10);
});
}
}