chartmogul-ruby 4.12.0 → 4.15.0
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 +4 -4
- data/.claude/hooks/post-edit-lint.sh +14 -0
- data/.claude/hooks/post-stop-validate.sh +44 -0
- data/.claude/hooks/session-start-setup.sh +42 -0
- data/.claude/settings.json +74 -0
- data/.gitignore +19 -0
- data/README.md +17 -1
- data/changelog.md +2 -150
- data/chartmogul-ruby.gemspec +5 -7
- data/lib/chartmogul/account.rb +15 -2
- data/lib/chartmogul/api/actions/update.rb +4 -2
- data/lib/chartmogul/api_resource.rb +35 -0
- data/lib/chartmogul/concerns/external_id_operations.rb +68 -0
- data/lib/chartmogul/concerns/toggle_disabled.rb +24 -0
- data/lib/chartmogul/contact.rb +55 -0
- data/lib/chartmogul/customer.rb +111 -13
- data/lib/chartmogul/entity_note.rb +41 -0
- data/lib/chartmogul/invoice.rb +10 -0
- data/lib/chartmogul/json_import.rb +45 -0
- data/lib/chartmogul/line_item.rb +60 -0
- data/lib/chartmogul/note.rb +51 -0
- data/lib/chartmogul/subscription.rb +2 -0
- data/lib/chartmogul/subscription_event.rb +62 -0
- data/lib/chartmogul/task.rb +3 -0
- data/lib/chartmogul/transaction.rb +33 -0
- data/lib/chartmogul/version.rb +1 -1
- data/lib/chartmogul.rb +6 -0
- data/zizmor.yml +7 -0
- metadata +13 -9
- data/.github/workflows/test.yml +0 -23
data/lib/chartmogul/contact.rb
CHANGED
|
@@ -7,6 +7,7 @@ module ChartMogul
|
|
|
7
7
|
set_immutable_keys([:custom])
|
|
8
8
|
|
|
9
9
|
readonly_attr :uuid
|
|
10
|
+
readonly_attr :historical_values
|
|
10
11
|
|
|
11
12
|
writeable_attr :customer_uuid
|
|
12
13
|
writeable_attr :data_source_uuid
|
|
@@ -20,8 +21,10 @@ module ChartMogul
|
|
|
20
21
|
writeable_attr :linked_in
|
|
21
22
|
writeable_attr :twitter
|
|
22
23
|
writeable_attr :notes
|
|
24
|
+
writeable_attr :last_seen
|
|
23
25
|
writeable_attr :external_id
|
|
24
26
|
writeable_attr :custom
|
|
27
|
+
writeable_attr :overrides
|
|
25
28
|
|
|
26
29
|
include API::Actions::Create
|
|
27
30
|
include API::Actions::Custom
|
|
@@ -38,6 +41,22 @@ module ChartMogul
|
|
|
38
41
|
true
|
|
39
42
|
end
|
|
40
43
|
|
|
44
|
+
def tasks(options = {})
|
|
45
|
+
Tasks.all(options.merge(contact_uuid: uuid))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def create_task(options = {})
|
|
49
|
+
Task.create!(with_associated_object_identifier(options))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def entity_notes(options = {})
|
|
53
|
+
EntityNotes.all(options.merge(contact_uuid: uuid))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def create_entity_note(options = {})
|
|
57
|
+
EntityNote.create!(with_associated_object_identifier(options))
|
|
58
|
+
end
|
|
59
|
+
|
|
41
60
|
def serialize_for_write
|
|
42
61
|
super.tap do |attributes|
|
|
43
62
|
attributes.clone.each do |attribute_name, attribute_value|
|
|
@@ -55,6 +74,42 @@ module ChartMogul
|
|
|
55
74
|
attributes[:external_id] = nil if instance_variable_defined?(:@external_id) && external_id.nil?
|
|
56
75
|
end
|
|
57
76
|
end
|
|
77
|
+
|
|
78
|
+
# Responses echo the current override state, so only overrides assigned by
|
|
79
|
+
# the caller are serialized: replaying an echoed `true` flag on a later
|
|
80
|
+
# update! would re-protect stale in-memory values on the server. The echoed
|
|
81
|
+
# hash is deep-frozen and `dup` copies only the top level — request changes
|
|
82
|
+
# by assigning a freshly built hash, not by editing or duplicating the
|
|
83
|
+
# reader's result. Assigned intent is cleared by the response
|
|
84
|
+
# of the successful write (every write endpoint echoes `overrides`); an
|
|
85
|
+
# endpoint that stopped echoing would leave it set and resend it on the
|
|
86
|
+
# next update!.
|
|
87
|
+
def overrides=(value)
|
|
88
|
+
@overrides_requested = true
|
|
89
|
+
@overrides = value
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def serialize_overrides
|
|
93
|
+
overrides if @overrides_requested
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def set_overrides(value)
|
|
99
|
+
@overrides_requested = false
|
|
100
|
+
@overrides = freeze_nested(value)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def freeze_nested(value)
|
|
104
|
+
value.each_value { |nested| freeze_nested(nested) } if value.is_a?(Hash)
|
|
105
|
+
value.freeze
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def with_associated_object_identifier(options)
|
|
109
|
+
return options if options[:customer_uuid] || options[:associated_object_identifier]
|
|
110
|
+
|
|
111
|
+
options.merge(associated_object_identifier: { associated_object: 'contact', method: 'uuid', value: uuid })
|
|
112
|
+
end
|
|
58
113
|
end
|
|
59
114
|
|
|
60
115
|
class Contacts < APIResource
|
data/lib/chartmogul/customer.rb
CHANGED
|
@@ -5,7 +5,7 @@ module ChartMogul
|
|
|
5
5
|
class Customer < APIResource
|
|
6
6
|
set_resource_name 'Customer'
|
|
7
7
|
set_resource_path '/v1/customers'
|
|
8
|
-
set_immutable_keys(%i[attributes custom])
|
|
8
|
+
set_immutable_keys(%i[attributes custom overrides historical_values])
|
|
9
9
|
|
|
10
10
|
readonly_attr :uuid
|
|
11
11
|
readonly_attr :id
|
|
@@ -22,6 +22,7 @@ module ChartMogul
|
|
|
22
22
|
readonly_attr :currency_sign
|
|
23
23
|
readonly_attr :data_source_uuids
|
|
24
24
|
readonly_attr :external_ids
|
|
25
|
+
readonly_attr :historical_values
|
|
25
26
|
|
|
26
27
|
writeable_attr :attributes
|
|
27
28
|
writeable_attr :external_id
|
|
@@ -38,6 +39,7 @@ module ChartMogul
|
|
|
38
39
|
writeable_attr :owner
|
|
39
40
|
writeable_attr :primary_contact
|
|
40
41
|
writeable_attr :website_url
|
|
42
|
+
writeable_attr :overrides
|
|
41
43
|
|
|
42
44
|
include API::Actions::Create
|
|
43
45
|
include API::Actions::Custom
|
|
@@ -57,6 +59,22 @@ module ChartMogul
|
|
|
57
59
|
all(external_id: external_id).first
|
|
58
60
|
end
|
|
59
61
|
|
|
62
|
+
def self.retrieve_attributes(customer_uuid, options = {})
|
|
63
|
+
path = ChartMogul::ResourcePath.new("/v1/customers/#{customer_uuid}/attributes")
|
|
64
|
+
custom_without_assign!(:get, path.apply_with_get_params(options))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.add_tags_by_email!(email, *tags)
|
|
68
|
+
custom_without_assign!(:post, '/v1/customers/attributes/tags', email: email, tags: tags)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.add_custom_attributes_by_email!(email, *custom_attrs, overrides: nil, **brace_less_attr)
|
|
72
|
+
custom_attrs << brace_less_attr unless brace_less_attr.empty?
|
|
73
|
+
body = { email: email, custom: custom_attrs }
|
|
74
|
+
body[:overrides] = overrides if overrides
|
|
75
|
+
custom_without_assign!(:post, '/v1/customers/attributes/custom', body)
|
|
76
|
+
end
|
|
77
|
+
|
|
60
78
|
def self.merge!(into_uuid:, from_uuid:)
|
|
61
79
|
options = {
|
|
62
80
|
from: { customer_uuid: from_uuid },
|
|
@@ -97,14 +115,26 @@ module ChartMogul
|
|
|
97
115
|
Contact.create!(options.merge(customer_uuid: uuid))
|
|
98
116
|
end
|
|
99
117
|
|
|
118
|
+
# @deprecated Use {#entity_notes} instead.
|
|
100
119
|
def notes(options = {})
|
|
120
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Customer#notes is deprecated. Use ChartMogul::Customer#entity_notes instead.'
|
|
101
121
|
Notes.all(options.merge(customer_uuid: uuid))
|
|
102
122
|
end
|
|
103
123
|
|
|
124
|
+
# @deprecated Use {#create_entity_note} instead.
|
|
104
125
|
def create_note(options = {})
|
|
126
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Customer#create_note is deprecated. Use ChartMogul::Customer#create_entity_note instead.'
|
|
105
127
|
Note.create!(options.merge(customer_uuid: uuid))
|
|
106
128
|
end
|
|
107
129
|
|
|
130
|
+
def entity_notes(options = {})
|
|
131
|
+
EntityNotes.all(options.merge(customer_uuid: uuid))
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def create_entity_note(options = {})
|
|
135
|
+
EntityNote.create!(options.merge(customer_uuid: uuid))
|
|
136
|
+
end
|
|
137
|
+
|
|
108
138
|
def opportunities(options = {})
|
|
109
139
|
Opportnities.all(options.merge(customer_uuid: uuid))
|
|
110
140
|
end
|
|
@@ -142,22 +172,49 @@ module ChartMogul
|
|
|
142
172
|
tags: tags)[:tags]
|
|
143
173
|
end
|
|
144
174
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
175
|
+
# The custom attribute helpers (including .add_custom_attributes_by_email!)
|
|
176
|
+
# take override flags via the overrides: keyword, shaped
|
|
177
|
+
# { custom: { Name: true } } — unlike create!/update!, where the same flags
|
|
178
|
+
# nest under { attributes: { custom: { Name: true } } }. In
|
|
179
|
+
# update_custom_attributes!, an attribute literally named `overrides` must
|
|
180
|
+
# be passed in a braced hash, since the bare keyword is taken:
|
|
181
|
+
# update_custom_attributes!({ overrides: 'value' }) updates the attribute
|
|
182
|
+
# update_custom_attributes!(overrides: { ... }) sends override flags
|
|
183
|
+
def add_custom_attributes!(*custom_attrs, overrides: nil, **brace_less_attr)
|
|
184
|
+
custom_attrs << brace_less_attr unless brace_less_attr.empty?
|
|
185
|
+
body = { custom: custom_attrs }
|
|
186
|
+
body[:overrides] = overrides if overrides
|
|
187
|
+
response = custom_without_assign!(:post,
|
|
188
|
+
"/v1/customers/#{uuid}/attributes/custom",
|
|
189
|
+
body)
|
|
190
|
+
sync_custom_attribute_overrides(response)
|
|
191
|
+
self.custom_attributes = response[:custom]
|
|
149
192
|
end
|
|
150
193
|
|
|
151
|
-
def update_custom_attributes!(custom_attrs = {})
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
194
|
+
def update_custom_attributes!(custom_attrs = {}, overrides: nil, **brace_less_attrs)
|
|
195
|
+
body = { custom: custom_attrs.merge(brace_less_attrs) }
|
|
196
|
+
body[:overrides] = overrides if overrides
|
|
197
|
+
response = custom_without_assign!(:put,
|
|
198
|
+
"/v1/customers/#{uuid}/attributes/custom",
|
|
199
|
+
body)
|
|
200
|
+
sync_custom_attribute_overrides(response)
|
|
201
|
+
self.custom_attributes = response[:custom]
|
|
155
202
|
end
|
|
156
203
|
|
|
157
|
-
def remove_custom_attributes!(*custom_attrs)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
204
|
+
def remove_custom_attributes!(*custom_attrs, overrides: nil, **brace_less_attr)
|
|
205
|
+
custom_attrs << brace_less_attr unless brace_less_attr.empty?
|
|
206
|
+
body = { custom: custom_attrs }
|
|
207
|
+
body[:overrides] = overrides if overrides
|
|
208
|
+
response = custom_without_assign!(:delete,
|
|
209
|
+
"/v1/customers/#{uuid}/attributes/custom",
|
|
210
|
+
body)
|
|
211
|
+
sync_custom_attribute_overrides(response)
|
|
212
|
+
self.custom_attributes = response[:custom]
|
|
213
|
+
response
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def retrieve_attributes(options = {})
|
|
217
|
+
self.class.retrieve_attributes(uuid, options)
|
|
161
218
|
end
|
|
162
219
|
|
|
163
220
|
def merge_into!(other_customer)
|
|
@@ -178,8 +235,49 @@ module ChartMogul
|
|
|
178
235
|
)
|
|
179
236
|
end
|
|
180
237
|
|
|
238
|
+
# Responses echo the current override state, so only overrides assigned by
|
|
239
|
+
# the caller are serialized: replaying an echoed `true` flag on a later
|
|
240
|
+
# update! would re-protect stale in-memory values on the server. The echoed
|
|
241
|
+
# hash is deep-frozen and `dup` copies only the top level — request changes
|
|
242
|
+
# by assigning a freshly built hash, not by editing or duplicating the
|
|
243
|
+
# reader's result. Assigned intent is cleared by the response
|
|
244
|
+
# of the successful write (every write endpoint echoes `overrides`); an
|
|
245
|
+
# endpoint that stopped echoing would leave it set and resend it on the
|
|
246
|
+
# next update!.
|
|
247
|
+
def overrides=(value)
|
|
248
|
+
@overrides_requested = true
|
|
249
|
+
@overrides = value
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def serialize_overrides
|
|
253
|
+
overrides if @overrides_requested
|
|
254
|
+
end
|
|
255
|
+
|
|
181
256
|
private
|
|
182
257
|
|
|
258
|
+
def set_overrides(value)
|
|
259
|
+
@overrides_requested = false
|
|
260
|
+
@overrides = freeze_nested(value)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def freeze_nested(value)
|
|
264
|
+
value.each_value { |nested| freeze_nested(nested) } if value.is_a?(Hash)
|
|
265
|
+
value.freeze
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# The custom attribute endpoints echo the customer's current custom
|
|
269
|
+
# attribute overrides, in the shape overrides[:attributes] uses. Synced
|
|
270
|
+
# through the read-only path so the flags are never marked for
|
|
271
|
+
# serialization; a pending explicitly assigned hash is not clobbered,
|
|
272
|
+
# keeping the serialize-exactly-once contract.
|
|
273
|
+
def sync_custom_attribute_overrides(response)
|
|
274
|
+
return if @overrides_requested || !response.key?(:overrides)
|
|
275
|
+
|
|
276
|
+
updated = (overrides || {}).reject { |key, _| key == :attributes }
|
|
277
|
+
updated[:attributes] = response[:overrides] unless response[:overrides].empty?
|
|
278
|
+
set_overrides(updated)
|
|
279
|
+
end
|
|
280
|
+
|
|
183
281
|
def tags=(tags)
|
|
184
282
|
@attributes[:tags] = tags
|
|
185
283
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChartMogul
|
|
4
|
+
class EntityNote < APIResource
|
|
5
|
+
set_resource_name 'EntityNote'
|
|
6
|
+
set_resource_path '/v1/notes'
|
|
7
|
+
|
|
8
|
+
readonly_attr :uuid
|
|
9
|
+
readonly_attr :associated_object
|
|
10
|
+
readonly_attr :associated_object_uuid
|
|
11
|
+
readonly_attr :author
|
|
12
|
+
|
|
13
|
+
writeable_attr :customer_uuid
|
|
14
|
+
writeable_attr :associated_object_identifier
|
|
15
|
+
writeable_attr :type
|
|
16
|
+
writeable_attr :text
|
|
17
|
+
writeable_attr :author_email
|
|
18
|
+
writeable_attr :call_duration
|
|
19
|
+
writeable_attr :created_at
|
|
20
|
+
writeable_attr :updated_at
|
|
21
|
+
|
|
22
|
+
include API::Actions::Create
|
|
23
|
+
include API::Actions::Destroy
|
|
24
|
+
include API::Actions::Retrieve
|
|
25
|
+
include API::Actions::Update
|
|
26
|
+
|
|
27
|
+
def self.all(options = {})
|
|
28
|
+
EntityNotes.all(options)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class EntityNotes < APIResource
|
|
33
|
+
set_resource_name 'EntityNotes'
|
|
34
|
+
set_resource_path '/v1/notes'
|
|
35
|
+
|
|
36
|
+
include Concerns::Entries
|
|
37
|
+
include Concerns::PageableWithCursor
|
|
38
|
+
|
|
39
|
+
set_entry_class EntityNote
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/chartmogul/invoice.rb
CHANGED
|
@@ -23,7 +23,17 @@ module ChartMogul
|
|
|
23
23
|
writeable_attr :due_date, type: :time
|
|
24
24
|
|
|
25
25
|
include API::Actions::Retrieve
|
|
26
|
+
include API::Actions::Update
|
|
26
27
|
include API::Actions::Destroy
|
|
28
|
+
include Concerns::ToggleDisabled
|
|
29
|
+
include Concerns::ExternalIdOperations
|
|
30
|
+
|
|
31
|
+
# Update the status of an invoice by external_id
|
|
32
|
+
def self.update_status!(data_source_uuid:, invoice_external_id:, status:)
|
|
33
|
+
path = "/v1/data_sources/#{CGI.escape(data_source_uuid)}/invoices/#{CGI.escape(invoice_external_id)}/status"
|
|
34
|
+
handling_errors { json_put(path, { status: status }) }
|
|
35
|
+
true
|
|
36
|
+
end
|
|
27
37
|
|
|
28
38
|
def serialize_line_items
|
|
29
39
|
line_items.map(&:serialize_for_write)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChartMogul
|
|
4
|
+
# JsonImport resource for bulk importing data via JSON.
|
|
5
|
+
# Use this to efficiently upload large datasets to a data source.
|
|
6
|
+
class JsonImport < APIResource
|
|
7
|
+
set_resource_name 'JsonImport'
|
|
8
|
+
set_resource_path '/v1/data_sources/:data_source_uuid/json_imports'
|
|
9
|
+
|
|
10
|
+
readonly_attr :id
|
|
11
|
+
readonly_attr :external_id
|
|
12
|
+
readonly_attr :status
|
|
13
|
+
readonly_attr :created_at
|
|
14
|
+
readonly_attr :updated_at
|
|
15
|
+
readonly_attr :error_count
|
|
16
|
+
readonly_attr :processed_count
|
|
17
|
+
|
|
18
|
+
# Create a new JSON import batch for a data source
|
|
19
|
+
# @param data_source_uuid [String] The UUID of the data source
|
|
20
|
+
# @param data [Hash] The import data (customers, plans, invoices, etc.)
|
|
21
|
+
def self.create!(data_source_uuid:, **data)
|
|
22
|
+
path = "/v1/data_sources/#{data_source_uuid}/json_imports"
|
|
23
|
+
resp = handling_errors do
|
|
24
|
+
connection.post(path) do |req|
|
|
25
|
+
req.headers['Content-Type'] = 'application/json'
|
|
26
|
+
req.body = JSON.dump(data)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys:)
|
|
30
|
+
new_from_json(json)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Retrieve the status of a JSON import
|
|
34
|
+
# @param data_source_uuid [String] The UUID of the data source
|
|
35
|
+
# @param id [String, Integer] The ID of the import
|
|
36
|
+
def self.retrieve(data_source_uuid:, id:)
|
|
37
|
+
path = "/v1/data_sources/#{data_source_uuid}/json_imports/#{id}"
|
|
38
|
+
resp = handling_errors do
|
|
39
|
+
connection.get(path)
|
|
40
|
+
end
|
|
41
|
+
json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys:)
|
|
42
|
+
new_from_json(json)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChartMogul
|
|
4
|
+
# Standalone LineItem resource for CRUD operations on existing line items.
|
|
5
|
+
# Note: For creating line items on invoices, use LineItems::Subscription or LineItems::OneTime.
|
|
6
|
+
class LineItem < APIResource
|
|
7
|
+
set_resource_name 'LineItem'
|
|
8
|
+
set_resource_path '/v1/line_items'
|
|
9
|
+
|
|
10
|
+
readonly_attr :uuid
|
|
11
|
+
readonly_attr :disabled
|
|
12
|
+
readonly_attr :disabled_at
|
|
13
|
+
readonly_attr :disabled_by
|
|
14
|
+
readonly_attr :invoice_uuid
|
|
15
|
+
readonly_attr :subscription_uuid
|
|
16
|
+
readonly_attr :edit_history_summary
|
|
17
|
+
readonly_attr :errors
|
|
18
|
+
|
|
19
|
+
writeable_attr :type
|
|
20
|
+
writeable_attr :subscription_external_id
|
|
21
|
+
writeable_attr :subscription_set_external_id
|
|
22
|
+
writeable_attr :plan_uuid
|
|
23
|
+
writeable_attr :service_period_start, type: :time
|
|
24
|
+
writeable_attr :service_period_end, type: :time
|
|
25
|
+
writeable_attr :amount_in_cents
|
|
26
|
+
writeable_attr :quantity
|
|
27
|
+
writeable_attr :discount_amount_in_cents
|
|
28
|
+
writeable_attr :discount_code
|
|
29
|
+
writeable_attr :discount_description
|
|
30
|
+
writeable_attr :tax_amount_in_cents
|
|
31
|
+
writeable_attr :transaction_fees_in_cents
|
|
32
|
+
writeable_attr :transaction_fees_currency
|
|
33
|
+
writeable_attr :external_id
|
|
34
|
+
writeable_attr :data_source_uuid
|
|
35
|
+
writeable_attr :prorated
|
|
36
|
+
writeable_attr :proration_type
|
|
37
|
+
writeable_attr :cancelled_at, type: :time
|
|
38
|
+
writeable_attr :description
|
|
39
|
+
writeable_attr :account_code
|
|
40
|
+
writeable_attr :event_order
|
|
41
|
+
|
|
42
|
+
include API::Actions::Retrieve
|
|
43
|
+
include API::Actions::Update
|
|
44
|
+
include API::Actions::Destroy
|
|
45
|
+
include Concerns::ToggleDisabled
|
|
46
|
+
include Concerns::ExternalIdOperations
|
|
47
|
+
|
|
48
|
+
# Create a line item for an invoice
|
|
49
|
+
# @param handle_as_user_edit [Boolean] If true, the change is treated as a user edit
|
|
50
|
+
def self.create!(invoice_uuid:, handle_as_user_edit: nil, **attributes)
|
|
51
|
+
path = build_query_path(
|
|
52
|
+
"/v1/import/invoices/#{invoice_uuid}/line_items",
|
|
53
|
+
handle_as_user_edit: handle_as_user_edit
|
|
54
|
+
)
|
|
55
|
+
resp = handling_errors { json_post(path, attributes) }
|
|
56
|
+
json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys:)
|
|
57
|
+
new_from_json(json)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/lib/chartmogul/note.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'forwardable'
|
|
4
4
|
|
|
5
5
|
module ChartMogul
|
|
6
|
+
# @deprecated Use {ChartMogul::EntityNote} instead. /v1/customer_notes is superseded by /v1/notes.
|
|
6
7
|
class Note < APIResource
|
|
7
8
|
set_resource_name 'CustomerNote'
|
|
8
9
|
set_resource_path '/v1/customer_notes'
|
|
@@ -23,11 +24,55 @@ module ChartMogul
|
|
|
23
24
|
include API::Actions::Retrieve
|
|
24
25
|
include API::Actions::Update
|
|
25
26
|
|
|
27
|
+
# @deprecated Use {ChartMogul::EntityNote.all} instead.
|
|
26
28
|
def self.all(options = {})
|
|
27
29
|
Notes.all(options)
|
|
28
30
|
end
|
|
31
|
+
|
|
32
|
+
# @deprecated Use {ChartMogul::EntityNote.create!} instead.
|
|
33
|
+
def self.create!(attributes = {})
|
|
34
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note.create! is deprecated. Use ChartMogul::EntityNote.create! instead.'
|
|
35
|
+
super
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @deprecated Use {ChartMogul::EntityNote.retrieve} instead.
|
|
39
|
+
def self.retrieve(uuid, options = {})
|
|
40
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note.retrieve is deprecated. Use ChartMogul::EntityNote.retrieve instead.'
|
|
41
|
+
super
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @deprecated Use {ChartMogul::EntityNote.update!} instead.
|
|
45
|
+
def self.update!(uuid, attributes = {})
|
|
46
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note.update! is deprecated. Use ChartMogul::EntityNote.update! instead.'
|
|
47
|
+
super
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @deprecated Use {ChartMogul::EntityNote.destroy!} instead.
|
|
51
|
+
def self.destroy!(options = {})
|
|
52
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note.destroy! is deprecated. Use ChartMogul::EntityNote.destroy! instead.'
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @deprecated Use {ChartMogul::EntityNote#create!} instead.
|
|
57
|
+
def create!
|
|
58
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note#create! is deprecated. Use ChartMogul::EntityNote#create! instead.'
|
|
59
|
+
super
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @deprecated Use {ChartMogul::EntityNote#update!} instead.
|
|
63
|
+
def update!
|
|
64
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note#update! is deprecated. Use ChartMogul::EntityNote#update! instead.'
|
|
65
|
+
super
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @deprecated Use {ChartMogul::EntityNote#destroy!} instead.
|
|
69
|
+
def destroy!
|
|
70
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Note#destroy! is deprecated. Use ChartMogul::EntityNote#destroy! instead.'
|
|
71
|
+
super
|
|
72
|
+
end
|
|
29
73
|
end
|
|
30
74
|
|
|
75
|
+
# @deprecated Use {ChartMogul::EntityNotes} instead.
|
|
31
76
|
class Notes < APIResource
|
|
32
77
|
set_resource_name 'CustomerNotes'
|
|
33
78
|
set_resource_path '/v1/customer_notes'
|
|
@@ -36,5 +81,11 @@ module ChartMogul
|
|
|
36
81
|
include Concerns::PageableWithCursor
|
|
37
82
|
|
|
38
83
|
set_entry_class Note
|
|
84
|
+
|
|
85
|
+
# @deprecated Use {ChartMogul::EntityNotes.all} instead.
|
|
86
|
+
def self.all(options = {})
|
|
87
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Notes.all is deprecated. Use ChartMogul::EntityNotes.all instead.'
|
|
88
|
+
super
|
|
89
|
+
end
|
|
39
90
|
end
|
|
40
91
|
end
|
|
@@ -42,6 +42,7 @@ module ChartMogul
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def self.all(customer_uuid, options = {})
|
|
45
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Subscription.all is deprecated. Use ChartMogul::Metrics::Customers::Subscriptions.all instead.'
|
|
45
46
|
Subscriptions.all(customer_uuid, options)
|
|
46
47
|
end
|
|
47
48
|
|
|
@@ -71,6 +72,7 @@ module ChartMogul
|
|
|
71
72
|
set_entry_class Subscription
|
|
72
73
|
|
|
73
74
|
def self.all(customer_uuid, options = {})
|
|
75
|
+
warn 'DEPRECATION WARNING: the method ChartMogul::Subscriptions.all is deprecated. Use ChartMogul::Metrics::Customers::Subscriptions.all instead.'
|
|
74
76
|
super(options.merge(customer_uuid: customer_uuid))
|
|
75
77
|
end
|
|
76
78
|
|
|
@@ -6,6 +6,8 @@ module ChartMogul
|
|
|
6
6
|
set_resource_path '/v1/subscription_events'
|
|
7
7
|
|
|
8
8
|
readonly_attr :id
|
|
9
|
+
readonly_attr :disabled
|
|
10
|
+
readonly_attr :disabled_at
|
|
9
11
|
writeable_attr :data_source_uuid
|
|
10
12
|
writeable_attr :customer_external_id
|
|
11
13
|
writeable_attr :subscription_set_external_id
|
|
@@ -49,11 +51,71 @@ module ChartMogul
|
|
|
49
51
|
:subscription_event)
|
|
50
52
|
end
|
|
51
53
|
|
|
54
|
+
# Instance method: destroys this subscription event
|
|
52
55
|
def destroy!
|
|
53
56
|
handling_errors do
|
|
54
57
|
connection.delete(resource_path.path, subscription_event: { id: instance_attributes[:id] })
|
|
55
58
|
end
|
|
56
59
|
end
|
|
60
|
+
|
|
61
|
+
# Class method: accepts both flat and envelope-wrapped params for backwards compatibility
|
|
62
|
+
# flat params. : SubscriptionEvent.destroy!(id: 123)
|
|
63
|
+
# envelope-wrapped params: SubscriptionEvent.destroy!(subscription_event: { id: 123 })
|
|
64
|
+
def self.destroy!(params = {})
|
|
65
|
+
body = params.key?(:subscription_event) ? params : { subscription_event: params }
|
|
66
|
+
handling_errors do
|
|
67
|
+
connection.delete(resource_path.path, body)
|
|
68
|
+
end
|
|
69
|
+
true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Toggle the disabled state of a subscription event.
|
|
73
|
+
# Note: SubscriptionEvent uses envelope-wrapped requests/responses ({ subscription_event: ... })
|
|
74
|
+
# unlike other resources, because the API requires this format for this endpoint.
|
|
75
|
+
def toggle_disabled!(disabled:, handle_as_user_edit: nil)
|
|
76
|
+
path = self.class.build_query_path(
|
|
77
|
+
"#{resource_path.path}/#{instance_attributes[:id]}/disabled_state",
|
|
78
|
+
handle_as_user_edit: handle_as_user_edit
|
|
79
|
+
)
|
|
80
|
+
resp = handling_errors { self.class.json_patch(path, { disabled: disabled }) }
|
|
81
|
+
json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys: self.class.immutable_keys)
|
|
82
|
+
assign_all_attributes(json[:subscription_event] || json)
|
|
83
|
+
self
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Update a subscription event by data_source_uuid and external_id.
|
|
87
|
+
# Uses envelope-wrapped body ({ subscription_event: ... }) as required by this API endpoint.
|
|
88
|
+
def self.update_by_external_id!(data_source_uuid:, external_id:, handle_as_user_edit: nil, **attributes)
|
|
89
|
+
path = build_query_path(resource_path.path, handle_as_user_edit: handle_as_user_edit)
|
|
90
|
+
resp = handling_errors do
|
|
91
|
+
json_patch(path, { subscription_event: attributes.merge(data_source_uuid: data_source_uuid, external_id: external_id) })
|
|
92
|
+
end
|
|
93
|
+
json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys:)
|
|
94
|
+
new_from_json(json[:subscription_event] || json)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Delete a subscription event by data_source_uuid and external_id
|
|
98
|
+
def self.destroy_by_external_id!(data_source_uuid:, external_id:, handle_as_user_edit: nil)
|
|
99
|
+
path = build_query_path(resource_path.path, handle_as_user_edit: handle_as_user_edit)
|
|
100
|
+
handling_errors do
|
|
101
|
+
connection.delete(path, subscription_event: { data_source_uuid: data_source_uuid, external_id: external_id })
|
|
102
|
+
end
|
|
103
|
+
true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Toggle disabled state of a subscription event by data_source_uuid and external_id.
|
|
107
|
+
# Uses envelope-wrapped body ({ subscription_event: ... }) as required by this API endpoint.
|
|
108
|
+
def self.toggle_disabled_by_external_id!(data_source_uuid:, external_id:, disabled:, handle_as_user_edit: nil)
|
|
109
|
+
path = build_query_path("#{resource_path.path}/disabled_state", handle_as_user_edit: handle_as_user_edit)
|
|
110
|
+
resp = handling_errors do
|
|
111
|
+
json_patch(path, {
|
|
112
|
+
subscription_event: { data_source_uuid: data_source_uuid, external_id: external_id },
|
|
113
|
+
disabled: disabled
|
|
114
|
+
})
|
|
115
|
+
end
|
|
116
|
+
json = ChartMogul::Utils::JSONParser.parse(resp.body, immutable_keys:)
|
|
117
|
+
new_from_json(json[:subscription_event] || json)
|
|
118
|
+
end
|
|
57
119
|
end
|
|
58
120
|
|
|
59
121
|
class SubscriptionEvents < APIResource
|
data/lib/chartmogul/task.rb
CHANGED
|
@@ -8,10 +8,13 @@ module ChartMogul
|
|
|
8
8
|
set_resource_path '/v1/tasks'
|
|
9
9
|
|
|
10
10
|
readonly_attr :task_uuid
|
|
11
|
+
readonly_attr :associated_object
|
|
12
|
+
readonly_attr :associated_object_uuid
|
|
11
13
|
readonly_attr :created_at
|
|
12
14
|
readonly_attr :updated_at
|
|
13
15
|
|
|
14
16
|
writeable_attr :customer_uuid
|
|
17
|
+
writeable_attr :associated_object_identifier
|
|
15
18
|
writeable_attr :task_details
|
|
16
19
|
writeable_attr :assignee
|
|
17
20
|
writeable_attr :due_date
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChartMogul
|
|
4
|
+
# Standalone Transaction resource for CRUD operations on existing transactions.
|
|
5
|
+
# Note: For creating transactions on invoices, use Transactions::Payment or Transactions::Refund.
|
|
6
|
+
class Transaction < APIResource
|
|
7
|
+
set_resource_name 'Transaction'
|
|
8
|
+
set_resource_path '/v1/transactions'
|
|
9
|
+
|
|
10
|
+
readonly_attr :uuid
|
|
11
|
+
readonly_attr :disabled
|
|
12
|
+
readonly_attr :disabled_at
|
|
13
|
+
readonly_attr :disabled_by
|
|
14
|
+
readonly_attr :invoice_uuid
|
|
15
|
+
readonly_attr :edit_history_summary
|
|
16
|
+
readonly_attr :errors
|
|
17
|
+
|
|
18
|
+
writeable_attr :type
|
|
19
|
+
writeable_attr :date, type: :time
|
|
20
|
+
writeable_attr :result
|
|
21
|
+
writeable_attr :external_id
|
|
22
|
+
writeable_attr :data_source_uuid
|
|
23
|
+
writeable_attr :amount_in_cents
|
|
24
|
+
writeable_attr :transaction_fees_in_cents
|
|
25
|
+
writeable_attr :transaction_fees_currency
|
|
26
|
+
|
|
27
|
+
include API::Actions::Retrieve
|
|
28
|
+
include API::Actions::Update
|
|
29
|
+
include API::Actions::Destroy
|
|
30
|
+
include Concerns::ToggleDisabled
|
|
31
|
+
include Concerns::ExternalIdOperations
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/chartmogul/version.rb
CHANGED