settings = $settings; } /** * 計算會費金額 * * @param Member $member 會員 * @param string $feeType 會費類型 (entrance_fee | annual_fee) * @return array{base_amount: float, discount_amount: float, final_amount: float, disability_discount: bool, fee_type: string} */ public function calculate(Member $member, string $feeType): array { $baseAmount = $this->getBaseAmount($feeType); $discountRate = $member->hasApprovedDisability() ? $this->getDisabilityDiscountRate() : 0; $discountAmount = round($baseAmount * $discountRate, 2); $finalAmount = round($baseAmount - $discountAmount, 2); return [ 'fee_type' => $feeType, 'base_amount' => $baseAmount, 'discount_amount' => $discountAmount, 'final_amount' => $finalAmount, 'disability_discount' => $discountRate > 0, ]; } /** * 為會員計算下一次應繳的會費 * * @param Member $member * @return array{base_amount: float, discount_amount: float, final_amount: float, disability_discount: bool, fee_type: string} */ public function calculateNextFee(Member $member): array { $feeType = $member->getNextFeeType(); return $this->calculate($member, $feeType); } /** * 取得基本會費金額 * * @param string $feeType * @return float */ public function getBaseAmount(string $feeType): float { return match($feeType) { MembershipPayment::FEE_TYPE_ENTRANCE => $this->getEntranceFee(), MembershipPayment::FEE_TYPE_ANNUAL => $this->getAnnualFee(), default => 0, }; } /** * 取得入會會費金額 * * @return float */ public function getEntranceFee(): float { return (float) $this->settings->get('membership_fee.entrance_fee', 1000); } /** * 取得常年會費金額 * * @return float */ public function getAnnualFee(): float { return (float) $this->settings->get('membership_fee.annual_fee', 1000); } /** * 取得身心障礙折扣比例 * * @return float 折扣比例 (0-1) */ public function getDisabilityDiscountRate(): float { return (float) $this->settings->get('membership_fee.disability_discount_rate', 0.5); } /** * 取得身心障礙折扣百分比 (用於顯示) * * @return int 百分比 (0-100) */ public function getDisabilityDiscountPercentage(): int { return (int) ($this->getDisabilityDiscountRate() * 100); } /** * 驗證繳費金額是否正確 * * @param MembershipPayment $payment * @return bool */ public function validatePaymentAmount(MembershipPayment $payment): bool { $member = $payment->member; $expected = $this->calculate($member, $payment->fee_type); // 繳費金額應等於或大於應繳金額 return $payment->amount >= $expected['final_amount']; } /** * 取得會費類型的標籤 * * @param string $feeType * @return string */ public function getFeeTypeLabel(string $feeType): string { return match($feeType) { MembershipPayment::FEE_TYPE_ENTRANCE => '入會會費', MembershipPayment::FEE_TYPE_ANNUAL => '常年會費', default => $feeType, }; } /** * 取得所有會費設定(用於管理界面) * * @return array */ public function getFeeSettings(): array { return [ 'entrance_fee' => $this->getEntranceFee(), 'annual_fee' => $this->getAnnualFee(), 'disability_discount_rate' => $this->getDisabilityDiscountRate(), 'disability_discount_percentage' => $this->getDisabilityDiscountPercentage(), ]; } }