$participants * * @method static \Illuminate\Database\Eloquent\Builder|Incentive newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Incentive newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Incentive query() * * @mixin \Eloquent */ class Incentive extends Model { use HasFactory, Sluggable, SoftDeletes; protected $table = 'incentives'; protected $casts = [ 'trans_name' => 'array', 'trans_subtitle' => 'array', 'trans_description' => 'array', 'trans_terms' => 'array', 'points_partner_onetime' => 'int', 'points_abo_onetime' => 'int', 'min_direct_partners' => 'int', 'min_customer_abos' => 'int', 'max_winners' => 'int', 'status' => 'int', 'qualification_start' => 'date', 'qualification_end' => 'date', 'calculation_end' => 'date', ]; protected $fillable = [ 'name', 'trans_name', 'subtitle', 'trans_subtitle', 'description', 'trans_description', 'image', 'terms', 'trans_terms', 'qualification_start', 'qualification_end', 'calculation_end', 'points_partner_onetime', 'points_abo_onetime', 'min_direct_partners', 'min_customer_abos', 'max_winners', 'status', ]; public static $statusTypes = [ 0 => 'draft', 1 => 'active', 2 => 'closed', ]; public static $statusColors = [ 0 => 'warning', 1 => 'success', 2 => 'secondary', ]; public function sluggable(): array { return [ 'slug' => [ 'source' => 'name', ], ]; } // Relationships public function participants() { return $this->hasMany(IncentiveParticipant::class); } // Scopes public function scopeActive($query) { return $query->where('status', 1); } public function scopeInQualificationPeriod($query, ?Carbon $date = null) { $date = $date ?: Carbon::now(); return $query->where('qualification_start', '<=', $date) ->where('qualification_end', '>=', $date); } public function scopeInCalculationPeriod($query, ?Carbon $date = null) { $date = $date ?: Carbon::now(); return $query->where('qualification_start', '<=', $date) ->where('calculation_end', '>=', $date); } // Helpers public function isActive(): bool { return $this->status === 1; } public function isDraft(): bool { return $this->status === 0; } public function isClosed(): bool { return $this->status === 2; } public function isInQualificationPeriod(?Carbon $date = null): bool { $date = $date ?: Carbon::now(); return $date->between($this->qualification_start, $this->qualification_end); } public function isInCalculationPeriod(?Carbon $date = null): bool { $date = $date ?: Carbon::now(); return $date->between($this->qualification_start, $this->calculation_end); } public function isDateInScope(int $month, int $year): bool { $date = Carbon::createFromDate($year, $month, 1); return $date->between( $this->qualification_start->copy()->startOfMonth(), $this->calculation_end->copy()->endOfMonth() ); } public function getStatusType(): string { return isset(self::$statusTypes[$this->status]) ? __('incentive.status_'.self::$statusTypes[$this->status]) : ''; } public function getStatusColor(): string { return self::$statusColors[$this->status] ?? 'default'; } /** * Get specific translation for a field and locale. */ public function getTrans(string $key, string $lang): string { $transKey = 'trans_'.$key; if (! empty($this->{$transKey}[$lang])) { return $this->{$transKey}[$lang]; } return ''; } /** * Get translated value for the current locale, falling back to German (default). */ public function getLang(string $key): string { $lang = \App::getLocale(); if ($lang === 'de') { return (string) ($this->{$key} ?? ''); } $trans = $this->getTrans($key, $lang); if ($trans !== '') { return $trans; } return (string) ($this->{$key} ?? ''); } /** * @return array */ public function getCalculationMonths(): array { $months = []; $current = $this->qualification_start->copy()->startOfMonth(); $end = $this->calculation_end->copy()->startOfMonth(); while ($current->lte($end)) { $months[] = [ 'month' => $current->month, 'year' => $current->year, ]; $current->addMonth(); } return $months; } }