formulas 0.1.1 → 0.1.1.4
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.
- checksums.yaml +4 -4
- data/formulas.gemspec +1 -1
- data/lib/formulas.rb +19 -0
- data/lib/formulas/paye.rb +10 -0
- data/lib/formulas/salary.rb +11 -11
- data/lib/formulas/student_loan_repayment.rb +3 -3
- data/lib/formulas/student_loan_repayment/fix_repayment_per_period.rb +6 -6
- data/lib/formulas/superannuation.rb +1 -1
- data/lib/formulas/withholding_tax.rb +23 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f95bf8ae022a90b5073d2421bdcad92aa870cc53c0a9c99db8954389e9c832c
|
4
|
+
data.tar.gz: a2502bbb84087d04237173f139ed0edd13b6adb172016a747f3c093a1e249416
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4382114d2679c7c9e622750bc24407441f70c689bffefb76293bf7de38077d62f34564e6c8d0dc845dccc19eba3d0836420aad03d5bab9a89de58ab2922a670
|
7
|
+
data.tar.gz: 6d687293ba712f2861b1a7dfd0f78da9a7ce0b0c40b9bd52923c35b17886b6aa9516549b3117497633c357fd8266b18628ec81b6d5a954d533c305f3260a9e77
|
data/formulas.gemspec
CHANGED
data/lib/formulas.rb
CHANGED
@@ -25,6 +25,13 @@ module Formulas
|
|
25
25
|
FREQUENCIES = [ANNUALLY, WEEKLY, FORTNIGHTLY, MONTHLY]
|
26
26
|
|
27
27
|
module FrequencyConversions
|
28
|
+
def convert_annually_to_annually(number)
|
29
|
+
number
|
30
|
+
end
|
31
|
+
alias :convert_weekly_to_weekly convert_annually_to_annually
|
32
|
+
alias :convert_fortnightly_to_fortnightly convert_annually_to_annually
|
33
|
+
alias :convert_monthly_to_monthly convert_annually_to_annually
|
34
|
+
|
28
35
|
def convert_annually_to_weekly(number)
|
29
36
|
number.to_f / 52
|
30
37
|
end
|
@@ -60,5 +67,17 @@ module Formulas
|
|
60
67
|
def convert_monthly_to_fortnightly(number)
|
61
68
|
number.to_f * 12 / 26
|
62
69
|
end
|
70
|
+
|
71
|
+
def convert_fortnightly_to_annually(number)
|
72
|
+
number.to_f * 26
|
73
|
+
end
|
74
|
+
|
75
|
+
def convert_fortnightly_to_weekly(number)
|
76
|
+
number.to_f / 2
|
77
|
+
end
|
78
|
+
|
79
|
+
def convert_fortnightly_to_monthly(number)
|
80
|
+
(number.to_f * 26) / 12
|
81
|
+
end
|
63
82
|
end
|
64
83
|
end
|
data/lib/formulas/paye.rb
CHANGED
@@ -19,6 +19,8 @@ module Formulas
|
|
19
19
|
[[180_000], 39]
|
20
20
|
]
|
21
21
|
|
22
|
+
MAX_ACC_LEVY_PAYABLE = 130_911
|
23
|
+
|
22
24
|
def initialize(gross_pay:, frequency: Formulas::MONTHLY)
|
23
25
|
super(gross_pay, frequency, TAX_RATES)
|
24
26
|
end
|
@@ -26,5 +28,13 @@ module Formulas
|
|
26
28
|
def tax(request_frequency: Formulas::WEEKLY)
|
27
29
|
calculate_tax(request_frequency)
|
28
30
|
end
|
31
|
+
|
32
|
+
def levy
|
33
|
+
0.0139
|
34
|
+
end
|
35
|
+
|
36
|
+
def acc_payable
|
37
|
+
annual_gross_pay > MAX_ACC_LEVY_PAYABLE ? MAX_ACC_LEVY_PAYABLE : annual_gross_pay
|
38
|
+
end
|
29
39
|
end
|
30
40
|
end
|
data/lib/formulas/salary.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Formulas
|
4
4
|
# Calculate basic salary in frequency
|
5
|
-
# salary = Formulas::Salary.new(
|
5
|
+
# salary = Formulas::Salary.new(pay: 52_000, Salary::ANNUAL)
|
6
6
|
#
|
7
7
|
# salary.pay(:monthly)
|
8
8
|
#
|
@@ -15,19 +15,19 @@ module Formulas
|
|
15
15
|
include FrequencyConversions
|
16
16
|
attr_reader :frequency
|
17
17
|
|
18
|
-
def initialize(
|
19
|
-
|
20
|
-
|
18
|
+
def initialize(pay:, frequency:)
|
19
|
+
@pay = pay
|
20
|
+
@frequency = frequency.to_sym
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
invalid_frequency unless FREQUENCIES.include?(@frequency)
|
23
|
+
raise ArgumentError, 'Gross pay must be numeric' unless Numeric === pay
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def pay(request_frequency: @frequency)
|
27
27
|
invalid_frequency unless FREQUENCIES.include?(frequency)
|
28
|
-
return @
|
28
|
+
return @pay if @frequency == request_frequency
|
29
29
|
|
30
|
-
|
30
|
+
convert_pay_to(request_frequency).round(2)
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
@@ -36,8 +36,8 @@ module Formulas
|
|
36
36
|
raise ArgumentError, "Invalid frequency, frequency are: #{FREQUENCIES.join(', ')}"
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
send("convert_#{@frequency}_to_#{request_frequency}", @
|
39
|
+
def convert_pay_to(request_frequency)
|
40
|
+
send("convert_#{@frequency}_to_#{request_frequency}", @pay)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -15,9 +15,9 @@ module Formulas
|
|
15
15
|
#
|
16
16
|
#
|
17
17
|
module StudentLoanRepayment
|
18
|
-
autoload :RepaymentBase, '
|
19
|
-
autoload :FixRepaymentPerPeriod, '
|
20
|
-
autoload :PercentRepaymentPerThreshold, '
|
18
|
+
autoload :RepaymentBase, 'formulas/student_loan_repayment/repayment_base'
|
19
|
+
autoload :FixRepaymentPerPeriod, 'formulas/student_loan_repayment/fix_repayment_per_period'
|
20
|
+
autoload :PercentRepaymentPerThreshold, 'formulas/student_loan_repayment/percent_repayment_per_threshold'
|
21
21
|
attr_reader :repayment
|
22
22
|
|
23
23
|
def initialize(income_strategy: , repayment_strategy:, rates:)
|
@@ -12,16 +12,16 @@ module Formulas
|
|
12
12
|
FIX_RATE = 0.12
|
13
13
|
|
14
14
|
DEFAULT_THRESHOLD = {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
weekly: [390, 52],
|
16
|
+
fortnightly: [780, 26],
|
17
|
+
four_weeks: [1560, 13],
|
18
|
+
monthly: [1690, 12],
|
19
|
+
annually: [20280, 1],
|
20
20
|
}
|
21
21
|
|
22
22
|
def repayment
|
23
23
|
selected_base = @repayment_threshold[@salary.frequency]
|
24
|
-
less_base_cost = @salary.
|
24
|
+
less_base_cost = @salary.pay - selected_base[0]
|
25
25
|
((FIX_RATE * less_base_cost * selected_base[1]) / 12).round(2)
|
26
26
|
end
|
27
27
|
end
|
@@ -24,7 +24,7 @@ module Formulas
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def calculate(request_frequency: Formulas::ANNUALLY)
|
27
|
-
result = @salary.
|
27
|
+
result = @salary.pay(request_frequency: request_frequency) * (@super.to_f / 100)
|
28
28
|
result.round(2)
|
29
29
|
end
|
30
30
|
end
|
@@ -4,10 +4,25 @@ module Formulas
|
|
4
4
|
class WithholdingTax
|
5
5
|
include FrequencyConversions
|
6
6
|
|
7
|
-
|
7
|
+
attr_reader :origin_frequency
|
8
|
+
|
9
|
+
def initialize(gross_pay, origin_frequency, tax_rate, options: {})
|
8
10
|
@gross_pay = gross_pay
|
9
11
|
@origin_frequency = origin_frequency
|
10
12
|
@tax_rate = tax_rate
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def net_pay(request_frequency:)
|
17
|
+
annual_pay_after_tax = annual_gross_pay - calculate_tax(Formulas::ANNUALLY)
|
18
|
+
|
19
|
+
if respond_to?(:levy)
|
20
|
+
net_pay = annual_pay_after_tax - (acc_payable * send(:levy))
|
21
|
+
end
|
22
|
+
|
23
|
+
return net_pay if request_frequency.to_s == Formulas::ANNUALLY.to_s
|
24
|
+
|
25
|
+
send("convert_annually_to_#{request_frequency}", net_pay).round(2)
|
11
26
|
end
|
12
27
|
|
13
28
|
protected
|
@@ -15,7 +30,7 @@ module Formulas
|
|
15
30
|
def calculate_tax(request_frequency)
|
16
31
|
@request_frequency = request_frequency
|
17
32
|
|
18
|
-
return annual_tax if request_frequency == Formulas::ANNUALLY
|
33
|
+
return annual_tax if request_frequency.to_s == Formulas::ANNUALLY.to_s
|
19
34
|
|
20
35
|
send("convert_annually_to_#{request_frequency}", annual_tax).round(2)
|
21
36
|
end
|
@@ -27,7 +42,7 @@ module Formulas
|
|
27
42
|
|
28
43
|
if gross_pay_tax_index > 0
|
29
44
|
@tax_rate[0..gross_pay_tax_index].each_with_index do |current, index|
|
30
|
-
l = (index == gross_pay_tax_index) ?
|
45
|
+
l = (index == gross_pay_tax_index) ? annual_gross_pay : current[0][1]
|
31
46
|
annual_result += ((l - current[0][0]) * (current[1].to_f / 100))
|
32
47
|
end
|
33
48
|
end
|
@@ -35,12 +50,15 @@ module Formulas
|
|
35
50
|
end
|
36
51
|
|
37
52
|
def annual_gross_pay
|
38
|
-
return @gross_pay if @origin_frequency == Formulas::ANNUALLY
|
53
|
+
return @gross_pay if @origin_frequency.to_s == Formulas::ANNUALLY.to_s
|
39
54
|
send("convert_#{@origin_frequency}_to_annually", @gross_pay)
|
40
55
|
end
|
41
56
|
|
42
57
|
def gross_pay_tax_index
|
43
|
-
@tax_rate.index
|
58
|
+
@tax_rate.index do |current|
|
59
|
+
(current[0][0] <= annual_gross_pay && current[0][1].nil?) ||
|
60
|
+
(current[0][0] <= annual_gross_pay && current[0][1] >= annual_gross_pay)
|
61
|
+
end
|
44
62
|
end
|
45
63
|
end
|
46
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formulas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1
|
4
|
+
version: 0.1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- formulas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|