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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: de1567f4fc4e2813c2e8a24d7c38d4972de4dd92
4
- data.tar.gz: e433e801af93c75c6d5dc056d9af3d34c236a0b3
2
+ SHA256:
3
+ metadata.gz: 56e5ae7abb7f48642d430ade7fa35c530b9dae71d9a62f8a8ba9b9e17aa4d9f3
4
+ data.tar.gz: 35c7a99568dfa8ce123f87445deef160fa2fa5ae7a4db857590cf84ae9b69499
5
5
  SHA512:
6
- metadata.gz: 0cb00109a6b6d23b477aa8c5b6b4c3304f8c39441bf42939f17624ab3e47300cb076727d7996dc44083f4596ae6487863016f2b0f3f5581dbd904d511c2b1878
7
- data.tar.gz: 7cf9c934466b6d9c4092f87f8f3af6aa60b18817786529f86599371b749991ccaf36717ebf68474f28ffafed8eb12f112d4a46e2e5173e6a4afc0415e364972b
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 next billing date for a recurring subscription.
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
@@ -1,3 +1,3 @@
1
1
  module BillingCycle
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  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.0.0
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: 2018-07-10 00:00:00.000000000 Z
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
- rubyforge_project:
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.