PayrollStatus::class, 'base_salary' => 'integer', 'bonus_amount' => 'integer', 'deduction_amount' => 'integer', 'total_amount' => 'integer', 'paid_at' => 'datetime', ]; } protected function formattedBaseSalary(): Attribute { return Attribute::make( get: fn () => 'Rp ' . number_format($this->base_salary, 0, ',', '.'), ); } protected function formattedBonusAmount(): Attribute { return Attribute::make( get: fn () => 'Rp ' . number_format($this->bonus_amount, 0, ',', '.'), ); } protected function formattedDeductionAmount(): Attribute { return Attribute::make( get: fn () => 'Rp ' . number_format($this->deduction_amount, 0, ',', '.'), ); } protected function formattedAmount(): Attribute { return Attribute::make( get: fn () => 'Rp ' . number_format($this->attributes['total_amount'] ?? 0, 0, ',', '.'), ); } protected function statusLabel(): Attribute { return Attribute::make( get: fn () => $this->status->label(), ); } protected function formattedTotalAmount(): Attribute { return Attribute::make( get: fn () => 'Rp ' . number_format($this->total_amount, 0, ',', '.'), ); } #[Scope] protected function cancelled(Builder $query): void { $query->where('status', PayrollStatus::CANCELLED); } #[Scope] protected function paid(Builder $query): void { $query->where('status', PayrollStatus::PAID); } #[Scope] protected function unpaid(Builder $query): void { $query->where('status', PayrollStatus::UNPAID); } public function cashTransaction(): BelongsTo { return $this->belongsTo(CashTransaction::class); } public function employee(): BelongsTo { return $this->belongsTo(Employee::class); } public function paidBy(): BelongsTo { return $this->belongsTo(User::class, 'paid_by_id'); } public function payrollAdjustments(): HasMany { return $this->hasMany(PayrollAdjustment::class); } public function payrollPeriod(): BelongsTo { return $this->belongsTo(PayrollPeriod::class); } }