elasticfin 0.1.3 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7ae623a3e2be66ba717462a42e6c20d7234fd26ad40d6bc57f01371260ce1e1
4
- data.tar.gz: e36d8a4452b4050026930d429288b974bfcb917932e9540a196c8ac5e7276452
3
+ metadata.gz: c78e701014b495c4f7e12b88a46d8f1de01ec24e444d1d9eef8a30a9a7f0bb6e
4
+ data.tar.gz: ec13a239c75b63583d8753a72b2ae168080d8699a8859e35df0566c0e590e4d5
5
5
  SHA512:
6
- metadata.gz: e7dee0a2344cbf4a3acd7e6e93fe605d1b8ab58afb9776a2836b3bc3a34b72d75e852056aa5174f282eb3611e4a2e1115bc5bd3909fd45728cd09d2ed334c291
7
- data.tar.gz: 3a749e9147315dd2ed6043519f71a44e46e1bb295c7b65106fdf2661d67c237752a482c51df30d7241569ffbfe89e96f312029304fc77f9c0b680edd2a0170d9
6
+ metadata.gz: 15f626f3542b2ac4048bc9c6535678e0a80d79339f724d662108c1bb2558d35cea1c118147b360b10ab0ef056cafd55fd6f941237cafc29133a8768a2bfc3954
7
+ data.tar.gz: 4eaaf8c667ddf1115a71b7ef122400a0343b8938af2d13442ed7bfbdc8d0b5e9376ec3e1edf541652d2f93d286ad7bb3ca6b2cc6dba1bcf00f3f2cdcd5db77a6
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Elasticfin
2
2
 
3
- Ruby wrapper for ElasticFin API
3
+ Ruby gem for Elasticfin billing and subscription management.
4
4
 
5
- ## Setup
5
+ ## Installation
6
6
 
7
7
  Add to Gemfile:
8
8
 
@@ -10,51 +10,90 @@ Add to Gemfile:
10
10
  gem 'elasticfin'
11
11
  ```
12
12
 
13
- Set your API key in env:
13
+ Set your API key:
14
14
 
15
15
  ```
16
16
  ELASTICFIN_KEY=your_key_here
17
17
  ```
18
18
 
19
+ ## Setup
20
+
21
+ Add to your customer model:
22
+
23
+ ```ruby
24
+ class User < ApplicationRecord
25
+ elasticfin_billable
26
+ end
27
+ ```
28
+
29
+ By default uses `:id` for external_id and auto-detects `:email` or `:email_address`.
30
+
31
+ Customize if needed:
32
+
33
+ ```ruby
34
+ elasticfin_billable external_id: :uuid, email: :contact_email
35
+ ```
36
+
19
37
  ## Usage
20
38
 
21
- ### Check entitlements
39
+ All methods are called on instances of your billable model:
40
+
41
+ ```ruby
42
+ customer = User.find(1)
43
+ customer.elasticfin_has_entitlement?("premium")
44
+
45
+ # Or with Current attributes
46
+ Current.user.elasticfin_checkout_url(price_id: "price_xxx")
47
+
48
+ # Works with any model name (User, Team, Account, etc)
49
+ team = Team.find(5)
50
+ team.elasticfin_billing_portal_url(return_url: "/settings")
51
+ ```
52
+
53
+ ### Sync Customers
54
+
55
+ Sync all customers to Elasticfin:
56
+
57
+ ```ruby
58
+ Elasticfin.sync_customers
59
+ ```
60
+
61
+ Sync a single customer:
22
62
 
23
63
  ```ruby
24
- Elasticfin.customer.has_entitlement?(team_id, "premium")
64
+ user.elasticfin_sync
25
65
  ```
26
66
 
27
- ### Create checkout
67
+ ### Check Entitlements
28
68
 
29
69
  ```ruby
30
- url = Elasticfin.checkout.create_session(team_id, email, price_id)
70
+ user.elasticfin_has_entitlement?("premium")
31
71
  ```
32
72
 
33
- ### Billing portal
73
+ ### Create Checkout
34
74
 
35
75
  ```ruby
36
- url = Elasticfin.billing.portal_url(team_id, return_url)
76
+ checkout_url = user.elasticfin_checkout_url(price_id: "price_xxx")
37
77
  ```
38
78
 
39
- ### Change plan
79
+ ### Billing Portal
40
80
 
41
81
  ```ruby
42
- url = Elasticfin.billing.change_plan_url(team_id, price_id, return_url)
82
+ portal_url = user.elasticfin_billing_portal_url(return_url: "https://yourapp.com/settings")
43
83
  ```
44
84
 
45
- ### Get customer info
85
+ ### Change Plan
46
86
 
47
87
  ```ruby
48
- provider = Elasticfin.customer.provider(team_id)
49
- interval = Elasticfin.customer.interval(team_id)
88
+ change_url = user.elasticfin_change_plan_url(
89
+ price_id: "price_yyy",
90
+ return_url: "https://yourapp.com/settings"
91
+ )
50
92
  ```
51
93
 
52
- ### Import customers
94
+ ### Get Customer Info
53
95
 
54
96
  ```ruby
55
- result = Elasticfin.customer.import([
56
- { external_id: "cust_1", email: "user1@example.com" },
57
- { external_id: "cust_2", email: "user2@example.com" }
58
- ])
59
- # Returns: { imported_count: 2, total_count: 2, errors: [] }
97
+ provider = user.elasticfin_provider # "stripe", etc
98
+ interval = user.elasticfin_interval # "month", "year", etc
60
99
  ```
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elasticfin
4
+ module Billable
5
+ def elasticfin_billable(external_id: :id, email: nil)
6
+ include InstanceMethods
7
+ extend ClassMethods
8
+
9
+ # Auto-detect email field if not provided
10
+ email_field = email || detect_email_field
11
+
12
+ # Store field configurations
13
+ class_variable_set(:@@elasticfin_external_id_field, external_id)
14
+ class_variable_set(:@@elasticfin_email_field, email_field)
15
+
16
+ # Register this model with Elasticfin
17
+ Elasticfin.register_billable_model(self)
18
+ end
19
+
20
+ def self.detect_email_field
21
+ if column_names.include?("email")
22
+ :email
23
+ elsif column_names.include?("email_address")
24
+ :email_address
25
+ else
26
+ raise Elasticfin::Error, "No email field found. Specify email field with: elasticfin_billable email: :your_email_field"
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+ def elasticfin_sync_all
32
+ Elasticfin.sync_customers
33
+ end
34
+
35
+ def elasticfin_external_id_field
36
+ class_variable_get(:@@elasticfin_external_id_field)
37
+ end
38
+
39
+ def elasticfin_email_field
40
+ class_variable_get(:@@elasticfin_email_field)
41
+ end
42
+
43
+ private
44
+
45
+ def detect_email_field
46
+ if column_names.include?("email")
47
+ :email
48
+ elsif column_names.include?("email_address")
49
+ :email_address
50
+ else
51
+ raise Elasticfin::Error, "No email field found. Specify email field with: elasticfin_billable email: :your_email_field"
52
+ end
53
+ end
54
+ end
55
+
56
+ module InstanceMethods
57
+ def elasticfin_external_id
58
+ send(self.class.elasticfin_external_id_field)
59
+ end
60
+
61
+ def elasticfin_email
62
+ send(self.class.elasticfin_email_field)
63
+ end
64
+
65
+ def elasticfin_sync
66
+ Elasticfin.sync_customer(self)
67
+ end
68
+
69
+ # Checkout
70
+ def elasticfin_checkout_url(price_id:)
71
+ Elasticfin.checkout.create_session(
72
+ elasticfin_external_id.to_s,
73
+ elasticfin_email,
74
+ price_id
75
+ )
76
+ end
77
+
78
+ # Entitlements
79
+ def elasticfin_has_entitlement?(entitlement_name)
80
+ Elasticfin.customer.has_entitlement?(
81
+ elasticfin_external_id.to_s,
82
+ entitlement_name
83
+ )
84
+ end
85
+
86
+ # Billing
87
+ def elasticfin_billing_portal_url(return_url:)
88
+ Elasticfin.billing.portal_url(
89
+ elasticfin_external_id.to_s,
90
+ return_url
91
+ )
92
+ end
93
+
94
+ def elasticfin_change_plan_url(price_id:, return_url:)
95
+ Elasticfin.billing.change_plan_url(
96
+ elasticfin_external_id.to_s,
97
+ price_id,
98
+ return_url
99
+ )
100
+ end
101
+
102
+ # Customer info
103
+ def elasticfin_provider
104
+ Elasticfin.customer.provider(elasticfin_external_id.to_s)
105
+ end
106
+
107
+ def elasticfin_interval
108
+ Elasticfin.customer.interval(elasticfin_external_id.to_s)
109
+ end
110
+ end
111
+ end
112
+ end
@@ -10,6 +10,8 @@ module Elasticfin
10
10
  end
11
11
 
12
12
  class << self
13
+ attr_accessor :billable_model
14
+
13
15
  def configuration
14
16
  @configuration ||= Configuration.new
15
17
  end
@@ -37,5 +39,34 @@ module Elasticfin
37
39
  def billing
38
40
  client.billing
39
41
  end
42
+
43
+ def register_billable_model(model)
44
+ if @billable_model && @billable_model != model
45
+ raise Error, "Billable model already registered as #{@billable_model.name}. Only one model can use elasticfin_billable."
46
+ end
47
+ @billable_model = model
48
+ end
49
+
50
+ def sync_customers
51
+ raise Error, "No billable model registered. Add elasticfin_billable to your model." unless billable_model
52
+
53
+ customers_data = billable_model.all.map do |record|
54
+ {
55
+ external_id: record.elasticfin_external_id.to_s,
56
+ email: record.elasticfin_email
57
+ }
58
+ end
59
+
60
+ customer.import(customers_data)
61
+ end
62
+
63
+ def sync_customer(record)
64
+ customer_data = [{
65
+ external_id: record.elasticfin_external_id.to_s,
66
+ email: record.elasticfin_email
67
+ }]
68
+
69
+ customer.import(customer_data)
70
+ end
40
71
  end
41
72
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Elasticfin
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.4"
5
5
  end
data/lib/elasticfin.rb CHANGED
@@ -6,7 +6,13 @@ require_relative "elasticfin/resources/customer"
6
6
  require_relative "elasticfin/resources/checkout"
7
7
  require_relative "elasticfin/resources/billing"
8
8
  require_relative "elasticfin/configuration"
9
+ require_relative "elasticfin/billable"
9
10
 
10
11
  module Elasticfin
11
12
  class Error < StandardError; end
12
13
  end
14
+
15
+ # Extend ActiveRecord::Base to make elasticfin_billable available on all models
16
+ if defined?(ActiveRecord::Base)
17
+ ActiveRecord::Base.extend Elasticfin::Billable
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticfin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - elasticfin
@@ -20,6 +20,7 @@ files:
20
20
  - README.md
21
21
  - Rakefile
22
22
  - lib/elasticfin.rb
23
+ - lib/elasticfin/billable.rb
23
24
  - lib/elasticfin/client.rb
24
25
  - lib/elasticfin/configuration.rb
25
26
  - lib/elasticfin/resources/billing.rb