billing_cycle 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Test Coverage](https://codeclimate.com/github/simplymadeapps/billing_cycle/badges/coverage.svg)](https://codeclimate.com/github/simplymadeapps/billing_cycle/coverage)
|
6
6
|
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](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.
|