self::STATUS_DRAFT, 'verification_status' => self::VERIFICATION_PENDING, 'execution_status' => self::EXECUTION_PENDING, ]; protected $fillable = [ 'finance_document_id', 'payee_name', 'payee_bank_code', 'payee_account_number', 'payee_bank_name', 'payment_amount', 'payment_method', 'created_by_accountant_id', 'payment_order_number', 'notes', 'verified_by_cashier_id', 'verified_at', 'verification_status', 'verification_notes', 'executed_by_cashier_id', 'executed_at', 'execution_status', 'transaction_reference', 'payment_receipt_path', 'status', ]; protected $casts = [ 'payment_amount' => 'decimal:2', 'verified_at' => 'datetime', 'executed_at' => 'datetime', ]; /** * 狀態常數 */ const STATUS_DRAFT = 'draft'; const STATUS_PENDING_VERIFICATION = 'pending_verification'; const STATUS_VERIFIED = 'verified'; const STATUS_EXECUTED = 'executed'; const STATUS_CANCELLED = 'cancelled'; const VERIFICATION_PENDING = 'pending'; const VERIFICATION_APPROVED = 'approved'; const VERIFICATION_REJECTED = 'rejected'; const EXECUTION_PENDING = 'pending'; const EXECUTION_COMPLETED = 'completed'; const EXECUTION_FAILED = 'failed'; const PAYMENT_METHOD_BANK_TRANSFER = 'bank_transfer'; const PAYMENT_METHOD_CHECK = 'check'; const PAYMENT_METHOD_CASH = 'cash'; /** * 關聯到報銷申請單 */ public function financeDocument(): BelongsTo { return $this->belongsTo(FinanceDocument::class); } /** * 會計製單人 */ public function createdByAccountant(): BelongsTo { return $this->belongsTo(User::class, 'created_by_accountant_id'); } /** * 出納覆核人 */ public function verifiedByCashier(): BelongsTo { return $this->belongsTo(User::class, 'verified_by_cashier_id'); } /** * 出納執行人 */ public function executedByCashier(): BelongsTo { return $this->belongsTo(User::class, 'executed_by_cashier_id'); } /** * 產生付款單號 */ public static function generatePaymentOrderNumber(): string { $date = now()->format('Ymd'); $latest = self::where('payment_order_number', 'like', "PO-{$date}%")->latest('id')->first(); if ($latest) { $lastNumber = (int) substr($latest->payment_order_number, -4); $newNumber = $lastNumber + 1; } else { $newNumber = 1; } return sprintf('PO-%s%04d', $date, $newNumber); } /** * 檢查是否可以被出納覆核 */ public function canBeVerifiedByCashier(): bool { return $this->status === self::STATUS_PENDING_VERIFICATION && $this->verification_status === self::VERIFICATION_PENDING; } /** * 檢查是否可以執行付款 */ public function canBeExecuted(): bool { return $this->status === self::STATUS_VERIFIED && $this->verification_status === self::VERIFICATION_APPROVED && $this->execution_status === self::EXECUTION_PENDING; } /** * 是否已執行 */ public function isExecuted(): bool { return $this->status === self::STATUS_EXECUTED && $this->execution_status === self::EXECUTION_COMPLETED; } /** * 取得付款方式文字 */ public function getPaymentMethodText(): string { return match ($this->payment_method) { self::PAYMENT_METHOD_BANK_TRANSFER => '銀行轉帳', self::PAYMENT_METHOD_CHECK => '支票', self::PAYMENT_METHOD_CASH => '現金', default => '未知', }; } /** * 取得狀態文字 */ public function getStatusText(): string { return match ($this->status) { self::STATUS_DRAFT => '草稿', self::STATUS_PENDING_VERIFICATION => '待出納覆核', self::STATUS_VERIFIED => '已覆核', self::STATUS_EXECUTED => '已執行付款', self::STATUS_CANCELLED => '已取消', default => '未知', }; } }