elasticfin 0.1.3 → 0.1.5

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: 6cf1202e392aa22187ef6aadf489a4c79ae1ebf595347e1f1b6f559f7e814acc
4
+ data.tar.gz: 8ada24734f3e69162cfb062f3309987c0d74e076be05e4f2e68dd51f8599aeae
5
5
  SHA512:
6
- metadata.gz: e7dee0a2344cbf4a3acd7e6e93fe605d1b8ab58afb9776a2836b3bc3a34b72d75e852056aa5174f282eb3611e4a2e1115bc5bd3909fd45728cd09d2ed334c291
7
- data.tar.gz: 3a749e9147315dd2ed6043519f71a44e46e1bb295c7b65106fdf2661d67c237752a482c51df30d7241569ffbfe89e96f312029304fc77f9c0b680edd2a0170d9
6
+ metadata.gz: 973de4dc109f63a9818bf4e0dbd876255b0e9f6a57f4c17a2efbd578547f88e5d8c4abbeff167a8982f69d7331bd1d3deaabddf214e8aec36c35e64f8b6646a0
7
+ data.tar.gz: 365489562e0b799b2b86b94b1a840f26cd20a3abd0b2592727b0acb7a3e2d139b392b0839f8335b297067a33887bb44a5b4351bccd3b9a8b95792f511f8766f6
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,98 @@ 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
+ **Options:**
32
+
33
+ ```ruby
34
+ elasticfin_billable external_id: :uuid, email: :contact_email
35
+ ```
36
+
37
+ **Auto-sync on create/update:**
38
+
39
+ ```ruby
40
+ elasticfin_billable auto_sync: true
41
+ ```
42
+
43
+ This automatically syncs customers to Elasticfin when created or when email/external_id changes.
44
+
19
45
  ## Usage
20
46
 
21
- ### Check entitlements
47
+ All methods are called on instances of your billable model:
48
+
49
+ ```ruby
50
+ customer = User.find(1)
51
+ customer.elasticfin_has_entitlement?("premium")
52
+
53
+ # Or with Current attributes
54
+ Current.user.elasticfin_checkout_url(price_id: "price_xxx")
55
+
56
+ # Works with any model name (User, Team, Account, etc)
57
+ team = Team.find(5)
58
+ team.elasticfin_billing_portal_url(return_url: "/settings")
59
+ ```
60
+
61
+ ### Sync Customers
62
+
63
+ Sync all customers to Elasticfin:
64
+
65
+ ```ruby
66
+ Elasticfin.sync_customers
67
+ ```
68
+
69
+ Sync a single customer:
22
70
 
23
71
  ```ruby
24
- Elasticfin.customer.has_entitlement?(team_id, "premium")
72
+ user.elasticfin_sync
25
73
  ```
26
74
 
27
- ### Create checkout
75
+ ### Check Entitlements
28
76
 
29
77
  ```ruby
30
- url = Elasticfin.checkout.create_session(team_id, email, price_id)
78
+ user.elasticfin_has_entitlement?("premium")
31
79
  ```
32
80
 
33
- ### Billing portal
81
+ ### Create Checkout
34
82
 
35
83
  ```ruby
36
- url = Elasticfin.billing.portal_url(team_id, return_url)
84
+ checkout_url = user.elasticfin_checkout_url(price_id: "price_xxx")
37
85
  ```
38
86
 
39
- ### Change plan
87
+ ### Billing Portal
40
88
 
41
89
  ```ruby
42
- url = Elasticfin.billing.change_plan_url(team_id, price_id, return_url)
90
+ portal_url = user.elasticfin_billing_portal_url(return_url: "https://yourapp.com/settings")
43
91
  ```
44
92
 
45
- ### Get customer info
93
+ ### Change Plan
46
94
 
47
95
  ```ruby
48
- provider = Elasticfin.customer.provider(team_id)
49
- interval = Elasticfin.customer.interval(team_id)
96
+ change_url = user.elasticfin_change_plan_url(
97
+ price_id: "price_yyy",
98
+ return_url: "https://yourapp.com/settings"
99
+ )
50
100
  ```
51
101
 
52
- ### Import customers
102
+ ### Get Customer Info
53
103
 
54
104
  ```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: [] }
105
+ provider = user.elasticfin_provider # "stripe", etc
106
+ interval = user.elasticfin_interval # "month", "year", etc
60
107
  ```
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elasticfin
4
+ module Billable
5
+ def elasticfin_billable(external_id: :id, email: nil, auto_sync: false)
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
+
19
+ # Add auto-sync callbacks if enabled
20
+ if auto_sync
21
+ after_create :elasticfin_sync
22
+ after_update :elasticfin_sync_if_changed
23
+ end
24
+ end
25
+
26
+ def self.detect_email_field
27
+ if column_names.include?("email")
28
+ :email
29
+ elsif column_names.include?("email_address")
30
+ :email_address
31
+ else
32
+ raise Elasticfin::Error, "No email field found. Specify email field with: elasticfin_billable email: :your_email_field"
33
+ end
34
+ end
35
+
36
+ module ClassMethods
37
+ def elasticfin_sync_all
38
+ Elasticfin.sync_customers
39
+ end
40
+
41
+ def elasticfin_external_id_field
42
+ class_variable_get(:@@elasticfin_external_id_field)
43
+ end
44
+
45
+ def elasticfin_email_field
46
+ class_variable_get(:@@elasticfin_email_field)
47
+ end
48
+
49
+ private
50
+
51
+ def detect_email_field
52
+ if column_names.include?("email")
53
+ :email
54
+ elsif column_names.include?("email_address")
55
+ :email_address
56
+ else
57
+ raise Elasticfin::Error, "No email field found. Specify email field with: elasticfin_billable email: :your_email_field"
58
+ end
59
+ end
60
+ end
61
+
62
+ module InstanceMethods
63
+ def elasticfin_external_id
64
+ send(self.class.elasticfin_external_id_field)
65
+ end
66
+
67
+ def elasticfin_email
68
+ send(self.class.elasticfin_email_field)
69
+ end
70
+
71
+ def elasticfin_sync
72
+ Elasticfin.sync_customer(self)
73
+ end
74
+
75
+ def elasticfin_sync_if_changed
76
+ id_field = self.class.elasticfin_external_id_field
77
+ email_field = self.class.elasticfin_email_field
78
+
79
+ if saved_change_to_attribute?(id_field) || saved_change_to_attribute?(email_field)
80
+ elasticfin_sync
81
+ end
82
+ end
83
+
84
+ # Checkout
85
+ def elasticfin_checkout_url(price_id:)
86
+ Elasticfin.checkout.create_session(
87
+ elasticfin_external_id.to_s,
88
+ elasticfin_email,
89
+ price_id
90
+ )
91
+ end
92
+
93
+ # Entitlements
94
+ def elasticfin_has_entitlement?(entitlement_name)
95
+ Elasticfin.customer.has_entitlement?(
96
+ elasticfin_external_id.to_s,
97
+ entitlement_name
98
+ )
99
+ end
100
+
101
+ # Billing
102
+ def elasticfin_billing_portal_url(return_url:)
103
+ Elasticfin.billing.portal_url(
104
+ elasticfin_external_id.to_s,
105
+ return_url
106
+ )
107
+ end
108
+
109
+ def elasticfin_change_plan_url(price_id:, return_url:)
110
+ Elasticfin.billing.change_plan_url(
111
+ elasticfin_external_id.to_s,
112
+ price_id,
113
+ return_url
114
+ )
115
+ end
116
+
117
+ # Customer info
118
+ def elasticfin_provider
119
+ Elasticfin.customer.provider(elasticfin_external_id.to_s)
120
+ end
121
+
122
+ def elasticfin_interval
123
+ Elasticfin.customer.interval(elasticfin_external_id.to_s)
124
+ end
125
+ end
126
+ end
127
+ 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.5"
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.5
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