billing_cycle 1.0.0 → 1.1.0
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 +5 -5
- data/README.md +77 -4
- data/lib/billing_cycle/billing_cycle.rb +37 -0
- data/lib/billing_cycle/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 56e5ae7abb7f48642d430ade7fa35c530b9dae71d9a62f8a8ba9b9e17aa4d9f3
|
4
|
+
data.tar.gz: 35c7a99568dfa8ce123f87445deef160fa2fa5ae7a4db857590cf84ae9b69499
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0577b5c653533ca5450de90f69570c1b6ccf89dac6f3ee14f0883d019d0939bd086f1023d7a3bc72dcef793cc8798b44cf019d41acd0df14c2269cc81514418d
|
7
|
+
data.tar.gz: c1c22e8c030535db87b7a2ab53bd535131f3fd61ecc935e1ce425f2150f24c8aa4e8e26805d8449f9f5e029d868958eb14f28ca05c0775973ea16d060f3c0877
|
data/README.md
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
[](https://codeclimate.com/github/simplymadeapps/billing_cycle/coverage)
|
6
6
|
[](http://www.rubydoc.info/github/simplymadeapps/billing_cycle/)
|
7
7
|
|
8
|
-
Billing Cycle is a gem used to calculate the
|
8
|
+
Billing Cycle is a gem used to calculate the billing due dates and time elapsed/remaining in
|
9
|
+
a recurring subscription's billing cycle.
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
@@ -23,6 +24,12 @@ $ bundle
|
|
23
24
|
|
24
25
|
## Usage
|
25
26
|
|
27
|
+
### Due Dates
|
28
|
+
|
29
|
+
Calculating due dates requires the original billing date as an anchor to determine due dates
|
30
|
+
in the future. `BillingCycle::BillingCycle` does the work to handle edge cases like having
|
31
|
+
a monthly subscription that started on the 31st when there's not 31 days in every month.
|
32
|
+
|
26
33
|
```ruby
|
27
34
|
original_billing_date = Time.zone.parse("2018-01-31 00:00:00")
|
28
35
|
billing_interval = 1.month
|
@@ -34,11 +41,15 @@ Time.zone.now
|
|
34
41
|
billing_cycle.next_due_at
|
35
42
|
# => Sat, 30 Jun 2018 00:00:00 CDT -05:00
|
36
43
|
|
37
|
-
billing_cycle.next_due_at(Time.zone.parse("2020-02-01 00:00:00")
|
38
|
-
# => Sat, 29 Feb 2020 00:00:00 CST -06:00
|
39
|
-
|
40
44
|
billing_cycle.previous_due_at
|
41
45
|
# => Thu, 31 May 2018 00:00:00 CDT -05:00
|
46
|
+
```
|
47
|
+
|
48
|
+
A time can be passed in as "now" instead of implicitly using the current time.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
billing_cycle.next_due_at(Time.zone.parse("2020-02-01 00:00:00")
|
52
|
+
# => Sat, 29 Feb 2020 00:00:00 CST -06:00
|
42
53
|
|
43
54
|
billing_cycle.previous_due_at(Time.zone.parse("2020-02-01 00:00:00")
|
44
55
|
# => Fri, 31 Jan 2020 00:00:00 CST -06:00
|
@@ -59,6 +70,67 @@ billing_cycle.previous_due_at
|
|
59
70
|
# => nil
|
60
71
|
```
|
61
72
|
|
73
|
+
### Time Elapsed and Remaining
|
74
|
+
|
75
|
+
The time elapsed and remaining can be used for displaying how much time has been used
|
76
|
+
and how much time is left in a billing cycle.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
original_billing_date = Time.zone.parse("2019-06-01 00:00:00")
|
80
|
+
billing_interval = 1.month
|
81
|
+
billing_cycle = BillingCycle::BillingCycle.new(original_billing_date, billing_interval)
|
82
|
+
|
83
|
+
Time.zone.now
|
84
|
+
# => Sun, 16 Jun 2019 00:00:00 CDT -05:00
|
85
|
+
|
86
|
+
billing_cycle.time_elapsed
|
87
|
+
# => 1296000.0 (seconds)
|
88
|
+
|
89
|
+
billing_cycle.time_remaining
|
90
|
+
# => 1296000.0 (seconds)
|
91
|
+
```
|
92
|
+
|
93
|
+
An interval can be passed in instead of implicitly using seconds and time can be passed in as "now"
|
94
|
+
instead of implicitly using the current time.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
billing_cycle.time_elapsed(1.day, Time.zone.parse("2019-06-07 00:00:00"))
|
98
|
+
# => 6.0 (days)
|
99
|
+
|
100
|
+
billing_cycle.time_remaining(1.day, Time.zone.parse("2019-06-07 00:00:00"))
|
101
|
+
# => 24.0 (days)
|
102
|
+
```
|
103
|
+
|
104
|
+
### Percent Elapsed and Remaining
|
105
|
+
|
106
|
+
The percent elapsed and remaining can be used for calculating subscription pricing when charging
|
107
|
+
or refunding for a partial billing cycle. The percentages are returned as a fraction of 1.0.
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
original_billing_date = Time.zone.parse("2019-06-01 00:00:00")
|
111
|
+
billing_interval = 1.month
|
112
|
+
billing_cycle = BillingCycle::BillingCycle.new(original_billing_date, billing_interval)
|
113
|
+
|
114
|
+
Time.zone.now
|
115
|
+
# => Sun, 16 Jun 2019 00:00:00 CDT -05:00
|
116
|
+
|
117
|
+
billing_cycle.percent_elapsed
|
118
|
+
# => 0.5
|
119
|
+
|
120
|
+
billing_cycle.percent_remaining
|
121
|
+
# => 0.5
|
122
|
+
```
|
123
|
+
|
124
|
+
A time can be passed in as "now" instead of implicitly using the current time.
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
billing_cycle.percent_elapsed(Time.zone.parse("2019-06-07 00:00:00"))
|
128
|
+
# => 0.2
|
129
|
+
|
130
|
+
billing_cycle.percent_remaining(Time.zone.parse("2019-06-07 00:00:00"))
|
131
|
+
# => 0.8
|
132
|
+
```
|
133
|
+
|
62
134
|
## Contributing
|
63
135
|
|
64
136
|
1. Fork it
|
@@ -68,4 +140,5 @@ billing_cycle.previous_due_at
|
|
68
140
|
5. Create new Pull Request
|
69
141
|
|
70
142
|
## License
|
143
|
+
|
71
144
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -35,6 +35,20 @@ module BillingCycle
|
|
35
35
|
next_due_at
|
36
36
|
end
|
37
37
|
|
38
|
+
# Returns the percentage of time that's elapsed between the previous due date and the next due date.
|
39
|
+
# @param now [Time] The current time
|
40
|
+
# @return [Float] The percentage as a fraction of 1.0
|
41
|
+
def percent_elapsed(now = Time.zone.now)
|
42
|
+
time_elapsed(1.second, now) / seconds_in_cycle(now)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the percentage of time that's remaining between the previous due date and the next due date.
|
46
|
+
# @param now [Time] The current time
|
47
|
+
# @return [Float] The percentage as a fraction of 1.0
|
48
|
+
def percent_remaining(now = Time.zone.now)
|
49
|
+
time_remaining(1.second, now) / seconds_in_cycle(now)
|
50
|
+
end
|
51
|
+
|
38
52
|
# Returns the previous billing date based on the subscription
|
39
53
|
# @param now [Time] The current time
|
40
54
|
# @return [Time] The previous billing date/time
|
@@ -55,6 +69,21 @@ module BillingCycle
|
|
55
69
|
previous_due_at
|
56
70
|
end
|
57
71
|
|
72
|
+
# Returns the time elapsed since the previous due date.
|
73
|
+
# @param interval [ActiveSupport::Duration] The duration
|
74
|
+
# @param now [Time] The current time
|
75
|
+
# @return [Float] The number of intervals since the previous due date
|
76
|
+
def time_elapsed(interval = 1.second, now = Time.zone.now)
|
77
|
+
(now - previous_due_at(now)) / interval
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the time remaining until the next due date.
|
81
|
+
# @param now [Time] The current time
|
82
|
+
# @return [Float] The number of intervals until the next due date
|
83
|
+
def time_remaining(interval = 1.second, now = Time.zone.now)
|
84
|
+
(next_due_at(now) - now) / interval
|
85
|
+
end
|
86
|
+
|
58
87
|
private
|
59
88
|
|
60
89
|
# Calculate the due date based on number of billing cycles since
|
@@ -86,9 +115,17 @@ module BillingCycle
|
|
86
115
|
end
|
87
116
|
|
88
117
|
# Returns the number billing cycles that have occurred between the created date and "now".
|
118
|
+
# @param now [Time] The current time
|
89
119
|
# @return [Integer]
|
90
120
|
def number_of_cycles_since_created(now)
|
91
121
|
(interval_value * ((now - created_at).to_i / interval)).to_i
|
92
122
|
end
|
123
|
+
|
124
|
+
# Returns the total number of seconds in the current billing cycle.
|
125
|
+
# @param now [Time] The current time
|
126
|
+
# @return [Float]
|
127
|
+
def seconds_in_cycle(now)
|
128
|
+
next_due_at(now) - previous_due_at(now)
|
129
|
+
end
|
93
130
|
end
|
94
131
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: billing_cycle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Pattison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -155,8 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
155
|
- !ruby/object:Gem::Version
|
156
156
|
version: '0'
|
157
157
|
requirements: []
|
158
|
-
|
159
|
-
rubygems_version: 2.5.2
|
158
|
+
rubygems_version: 3.0.3
|
160
159
|
signing_key:
|
161
160
|
specification_version: 4
|
162
161
|
summary: Utility for calculating the next billing date for a recurring subscription.
|