finrb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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