class ACCOUNT create make feature -- Access balance: REAL_64 -- Kontostand creditline: REAL_64 assign set_creditline -- Kreditrahmen interest_deposit: REAL_64 assign set_interest_deposit -- Habenverzinsung interest_debit: REAL_64 assign set_interest_debit -- Sollverzinsung transfer_minamount: REAL_64 assign set_transfer_minamount -- Mindestbetrag fuer jede Einzahlung, Auszahlung und Ueberweisung feature {NONE} -- Implementation range: detachable TUPLE [min: REAL_64; max: REAL_64] creditline_range: attached like range -- min/max for creditline interest_deposit_range: attached like range -- min/max for interest_deposit interest_debit_range: attached like range -- min/max for interest_debit authorized_signers: ARRAYED_SET [PERSON] -- Zeichnungsberechtigte feature {NONE} -- Initialization make (an_authorized_signer: PERSON; an_interest_deposit: like interest_deposit; an_interest_debit: like interest_debit; a_credit_line: like creditline; an_interest_deposit_range: like interest_deposit_range; an_interest_debit_range: like interest_debit_range; a_credit_line_range: like creditline_range) require a_credit_line_range.min < a_credit_line_range.max an_interest_debit_range.min < an_interest_debit_range.max an_interest_deposit_range.min < an_interest_deposit_range.max do create authorized_signers.make(1) add_authorized_signer (an_authorized_signer) creditline := a_credit_line interest_debit := an_interest_debit interest_deposit := an_interest_deposit interest_deposit_range := an_interest_deposit_range interest_debit_range := an_interest_debit_range creditline_range := a_credit_line_range set_default_transfer_minamount balance := 0.0 end feature -- Basic operations deposit (an_amount: like transfer_minamount; an_authorized_signer: PERSON) require an_authorized_signer_authorized: get_authorized_signers.has (an_authorized_signer) transfer_minamount_ok: an_amount >= transfer_minamount do balance := balance + an_amount ensure balance_increased: balance > old balance deposited: balance = old balance + an_amount end withdraw (an_amount: like transfer_minamount; an_authorized_signer: PERSON) require an_authorized_signer_authorized: get_authorized_signers.has (an_authorized_signer) transfer_minamount_ok: an_amount >= transfer_minamount balance_beneath_creditline: balance - an_amount >= creditline do balance := balance - an_amount ensure balance_beneath_creditline: balance >= creditline balance_decreased: balance < old balance withdrawed: balance = old balance - an_amount end transfer(an_amount: like transfer_minamount; an_authorized_signer: PERSON; an_account: like Current; another_authorized_signer: PERSON) require recipient_account_not_same: Current /= an_account do withdraw (an_amount, an_authorized_signer) an_account.deposit (an_amount, another_authorized_signer) end add_authorized_signer (an_authorized_signer: PERSON) do if not authorized_signers.has (an_authorized_signer) then authorized_signers.put (an_authorized_signer) end ensure authorized_signers_assigned: authorized_signers.has (an_authorized_signer) end remove_authorized_signer (an_authorized_signer: PERSON) require authorized_signer_exists: (get_authorized_signers.has (an_authorized_signer)) authorized_signers_not_empty: get_authorized_signers.count >= 2 do authorized_signers.prune (an_authorized_signer) ensure authorized_signers_assigned: not authorized_signers.has (an_authorized_signer) end get_authorized_signers: FINITE [PERSON] do Result := authorized_signers end advance do if balance < 0.0 then -- debit balance := balance + (balance * interest_debit) else -- deposit balance := balance + (balance * interest_deposit) end end feature {NONE} -- Implementation set_transfer_minamount (a_transfer_minamount: like transfer_minamount) require a_transfer_minamount_positive: a_transfer_minamount > 0.0 do transfer_minamount := a_transfer_minamount ensure transfer_minamount_assigned: transfer_minamount = a_transfer_minamount end set_default_transfer_minamount do set_transfer_minamount (2.0) end set_creditline (a_creditline: like creditline) require a_creditline_within_bounds: a_creditline >= creditline_range.min and a_creditline <= creditline_range.max do creditline := a_creditline ensure creditline_assigned: creditline = a_creditline end set_interest_deposit (an_interest_deposit: like interest_deposit) require an_interest_deposit_within_bounds: interest_deposit >= interest_deposit_range.min and interest_deposit <= interest_deposit_range.max do interest_deposit := an_interest_deposit ensure interest_deposit_assigned: interest_deposit = an_interest_deposit end set_interest_debit (an_interest_debit: like interest_debit) require an_interest_deposit_within_bounds: interest_debit >= interest_debit_range.min and interest_debit <= interest_debit_range.max do interest_debit := an_interest_debit ensure interest_debit_assigned: interest_debit = an_interest_debit end invariant authorized_signers_not_empty: authorized_signers.count > 0 transfer_minamount_positive: transfer_minamount > 0.0 creditline_within_bounds: creditline >= creditline_range.min and creditline <= creditline_range.max interest_debit_within_bounds: interest_debit >= interest_debit_range.min and interest_debit <= interest_debit_range.max interest_deposit_within_bounds: interest_deposit >= interest_deposit_range.min and interest_deposit <= interest_deposit_range.max end