profitable 0.2.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd833a8b05f27ea248099d3965e9d491a13f90c51c0ad29aa524384d6b92ddce
4
- data.tar.gz: 3b57ba527cc3ac287688222be53415d16f9bdf2635b07496883e50da3671e77f
3
+ metadata.gz: bf77ba92fb941bb21624c1f677bbfff37d874fefa06050e1fe6b395ae55ea3e2
4
+ data.tar.gz: 8d4cf7614e186d7082692faa36794916111205293a45aac055565c2e7923a24b
5
5
  SHA512:
6
- metadata.gz: daf28e6f4a6da261bb56fce23abb8a0a4f417d2c637eff0c1d696abcd19ebd7f123a283eddffbf66509ef9edf08f4e2ca4e0d9818c64ee9b2f7a188c7dafd2ca
7
- data.tar.gz: 982180e6b08385d430a3a7576d9e474ff96d108d086aec428272ca2d2399489eb663837efe85f0b03fe830350cab72ab25e264d498951fed1f4cef72c6231ccf
6
+ metadata.gz: 73c2251e3d2566b1d22f7319d179f9d8f1077dd70354add0fb8718232f094f613fd4aef048a0accbba8214d5ac4911497d4c6704199cf17470be6ed5ad485e06
7
+ data.tar.gz: 30abc5f18398a6e1553effc66b59407f43610a90a01448dae90dab8eeb74198921593c3e6cb8bea9b63cce14f9435eccb69a53c1d71912b9214392b3e7375e20
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # `profitable`
2
2
 
3
+ ## [0.2.1] - 2024-08-31
4
+
5
+ - Add syntactic sugar for `estimated_valuation(at: "3x")`
6
+ - Now `estimated_valuation` also supports `Numeric`-only inputs like `estimated_valuation(3)`, so that @pretzelhands can avoid writing 3 extra characters and we embrace actual syntactic sugar instead of "syntactic saccharine" (sic.)
7
+
3
8
  ## [0.2.0] - 2024-08-31
4
9
 
5
10
  - Initial production ready release
data/README.md CHANGED
@@ -59,7 +59,7 @@ All methods return numbers that can be converted to a nicely-formatted, human-re
59
59
  - `Profitable.churned_mrr(in_the_last: 30.days)`: MRR lost due to churn in the specified period
60
60
  - `Profitable.average_revenue_per_customer`: Average revenue per customer (ARPC)
61
61
  - `Profitable.lifetime_value`: Estimated customer lifetime value (LTV)
62
- - `Profitable.estimated_valuation(multiplier = "3x")`: Estimated company valuation based on ARR
62
+ - `Profitable.estimated_valuation(at: "3x")`: Estimated company valuation based on ARR
63
63
 
64
64
  ### Customer metrics
65
65
 
@@ -101,7 +101,10 @@ Profitable.churn(in_the_last: 3.months).to_readable # => "12%"
101
101
  Profitable.new_mrr(in_the_last: 24.hours).to_readable(2) # => "$123.45"
102
102
 
103
103
  # Get the estimated valuation at 5x ARR
104
- Profitable.estimated_valuation("5x").to_readable # => "$500,000"
104
+ Profitable.estimated_valuation(at: "5x").to_readable # => "$500,000"
105
+
106
+ # You can also pass the multiplier as a number, and/or ignore the "at:" keyword altogether
107
+ Profitable.estimated_valuation(4.5).to_readable # => "$450,000"
105
108
 
106
109
  # Get the time to next MRR milestone
107
110
  Profitable.time_to_next_mrr_milestone.to_readable # => "26 days left to $10,000 MRR"
@@ -128,24 +131,6 @@ Profitable.mrr # => 123456
128
131
  - `mrr_growth_rate`: This calculation compares the MRR at the start and end of the specified period. It assumes a linear growth rate over the period, which may not reflect short-term fluctuations. For more accurate results, consider using shorter periods or implementing a more sophisticated growth calculation method if needed.
129
132
  - `time_to_next_mrr_milestone`: This estimation is based on the current MRR and the recent growth rate. It assumes a constant growth rate, which may not reflect real-world conditions. The calculation may be inaccurate for very new businesses or those with irregular growth patterns.
130
133
 
131
- ## Mount the `/profitable` dashboard
132
-
133
- We also provide a simple dashboard with good defaults to see your main business metrics.
134
-
135
- In your `config/routes.rb` file, mount the `profitable` engine:
136
- ```ruby
137
- mount Profitable::Engine => '/profitable'
138
- ```
139
-
140
- It's a good idea to make sure you're adding some sort of authentication to the `/profitable` route to avoid exposing sensitive information:
141
- ```ruby
142
- authenticate :user, ->(user) { user.admin? } do
143
- mount Profitable::Engine => '/profitable'
144
- end
145
- ```
146
-
147
- You can now navigate to `/profitable` to see your app's business metrics like MRR, ARR, churn, etc.
148
-
149
134
  ## Development
150
135
 
151
136
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profitable
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/lib/profitable.rb CHANGED
@@ -46,8 +46,9 @@ module Profitable
46
46
  NumericResult.new(calculate_recurring_revenue_percentage(in_the_last), :percentage)
47
47
  end
48
48
 
49
- def estimated_valuation(multiplier = "3x")
50
- NumericResult.new(calculate_estimated_valuation(multiplier))
49
+ def estimated_valuation(multiplier = 3, at: nil)
50
+ actual_multiplier = at || multiplier
51
+ NumericResult.new(calculate_estimated_valuation(actual_multiplier))
51
52
  end
52
53
 
53
54
  def total_customers
@@ -127,11 +128,26 @@ module Profitable
127
128
  (mrr.to_f * 12).round
128
129
  end
129
130
 
130
- def calculate_estimated_valuation(multiplier = "3x")
131
- multiplier = multiplier.to_s.gsub('x', '').to_f
131
+ def calculate_estimated_valuation(multiplier = 3)
132
+ multiplier = parse_multiplier(multiplier)
132
133
  (calculate_arr * multiplier).round
133
134
  end
134
135
 
136
+ def parse_multiplier(input)
137
+ case input
138
+ when Numeric
139
+ input.to_f
140
+ when String
141
+ if input.end_with?('x')
142
+ input.chomp('x').to_f
143
+ else
144
+ input.to_f
145
+ end
146
+ else
147
+ 3.0 # Default multiplier if input is invalid
148
+ end.clamp(0.1, 100) # Ensure multiplier is within a reasonable range
149
+ end
150
+
135
151
  def calculate_churn(period = DEFAULT_PERIOD)
136
152
  start_date = period.ago
137
153
  total_subscribers_start = Pay::Subscription.active.where('created_at < ?', start_date).distinct.count('customer_id')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: profitable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rameerez