finrb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'decimal'
4
+
5
+ module Finrb
6
+ # the Transaction class provides a general interface for working with individual cash flows.
7
+ # @api public
8
+ class Transaction
9
+ # @return [DecNum] the cash value of the transaction
10
+ # @api public
11
+ attr_reader :amount
12
+ # @return [Integer] the period number of the transaction
13
+ # @note this attribute is mainly used in the case of mortgage amortization with no dates
14
+ # @api public
15
+ attr_accessor :period
16
+ # @return [Date] the date of the transaction
17
+ # @api public
18
+ attr_accessor :date
19
+
20
+ # create a new Transaction
21
+ # @return [Transaction]
22
+ # @param [Numeric] amount the cash value of the transaction
23
+ # @param [optional, Hash] opts sets optional attributes
24
+ # @option opts [String] :period the period number of the transaction
25
+ # @example a simple transaction
26
+ # t = Transaction.new(400)
27
+ # @example a transaction with a period number
28
+ # t = Transaction.new(400, :period => 3)
29
+ # @api public
30
+ def initialize(amount, opts = {})
31
+ @amount = amount
32
+ @original = amount
33
+
34
+ # Set optional attributes..
35
+ opts.each do |key, value|
36
+ send("#{key}=", value)
37
+ end
38
+ end
39
+
40
+ # Set the cash value of the transaction
41
+ # @return None
42
+ # @param [Numeric] value the cash value
43
+ # @example
44
+ # t = Transaction.new(500)
45
+ # t.amount = 750
46
+ # t.amount #=> 750
47
+ # @api public
48
+ def amount=(value)
49
+ @amount = Flt::DecNum.new(value.to_s) || 0
50
+ end
51
+
52
+ # @return [DecNum] the difference between the original transaction
53
+ # amount and the current amount
54
+ # @example
55
+ # t = Transaction.new(500)
56
+ # t.amount = 750
57
+ # t.difference #=> DecNum('250')
58
+ # @api public
59
+ def difference
60
+ @amount - @original
61
+ end
62
+
63
+ # @return [Boolean] whether or not the Transaction is an Interest transaction
64
+ # @example
65
+ # pmt = Payment.new(500)
66
+ # int = Interest.new(500)
67
+ # pmt.interest? #=> False
68
+ # int.interest? #=> True
69
+ # @api public
70
+ def interest?
71
+ instance_of?(Interest)
72
+ end
73
+
74
+ # @api public
75
+ def inspect
76
+ "Transaction(#{@amount.round(2)}, date: #{@date})"
77
+ end
78
+
79
+ # Modify a Transaction's amount by passing a block
80
+ # @return none
81
+ # @note self is passed as the argument to the block. This makes any public attribute available.
82
+ # @example add $100 to a monthly payment
83
+ # pmt = Payment.new(-500)
84
+ # pmt.modify { |t| t.amount-100 }
85
+ # pmt.amount #=> -600
86
+ # @api public
87
+ def modify
88
+ @amount = yield(self)
89
+ end
90
+
91
+ # (see #amount)
92
+ # @deprecated Provided for backwards compatibility
93
+ def payment
94
+ @amount
95
+ end
96
+
97
+ # @return [Boolean] whether or not the Transaction is a Payment transaction
98
+ # @example
99
+ # pmt = Payment.new(500)
100
+ # int = Interest.new(500)
101
+ # pmt.payment? #=> True
102
+ # int.payment? #=> False
103
+ # @api public
104
+ def payment?
105
+ instance_of?(Payment)
106
+ end
107
+ end
108
+
109
+ # Represent an interest charge as a Transaction
110
+ # @see Transaction
111
+ class Interest < Transaction
112
+ def inspect
113
+ "Interest(#{@amount})"
114
+ end
115
+ end
116
+
117
+ # Represent a loan payment as a Transaction
118
+ # @see Transaction
119
+ class Payment < Transaction
120
+ def inspect
121
+ "Payment(#{@amount})"
122
+ end
123
+ end
124
+ end