intacct-rest 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa26a0193bf0a743c64e8b7a0872a17922be601d53bb0a8f809aa09d33bee382
4
- data.tar.gz: 1d27d3c95af15ddf66d879fb8c08d86a7b0f67c223034606dff1df8cf1e32624
3
+ metadata.gz: 5a6731f918358600559712cf46245ade06051c5baad36679f586098ba8292ce7
4
+ data.tar.gz: '08a147feac379d3549d35d7ac345796ac2686d22ae605f2d857cdf625c0011ba'
5
5
  SHA512:
6
- metadata.gz: f8d45d6db98887b8af8974e601fff28d4c8534d8d52147b41d8336c2f2da4865864fde4c146a978d20dac67f32ebda91eb4e459ccbf83d5a6077cc5ff62954f8
7
- data.tar.gz: d2c3b257318be66c710a2c008ccb4b65d2e719e3ee9e35701511ac0cfd3358a6c42ab98214647490426e28f295b40678abba1a7b8c28340ae40eb75933edae4b
6
+ metadata.gz: 21137e073809b557d7f6fe00595c60423e85b04d0616683a6826e7c29ada6f645a4b2069d8596164c2c4c80b53e16182232112dfaf5c7ade25a3971aac29e16b
7
+ data.tar.gz: 1e962684b6d9ee8838c83be7b2dc3ba04471cd5ff578296ba55a7f09431c4575dcbf9f7b033eae9e61afd0ace2ebdc923108bda184fc189d3ceb909910d8cf55
data/README.md CHANGED
@@ -14,7 +14,8 @@ A small, framework-agnostic Ruby client for [Sage Intacct's REST API v1](https:/
14
14
  - **`IntacctRest::Model::Contact`**, a data + validation object for the non-deprecated subset of the contact shape shared by vendors and customers (no dedicated create endpoint — contacts are referenced by id from `contacts`/`contact_list`; this is just a typed helper for building that nested payload)
15
15
  - **The `POST /objects/accounts-payable/bill` endpoint**, via `IntacctRest::Endpoints::CreateBill` and `IntacctRest::Model::Bill`, reusing the same `Post`/validation pattern
16
16
  - **The `POST /objects/accounts-payable/bill-line` endpoint**, via `IntacctRest::Endpoints::CreateBillLine` and `IntacctRest::Model::BillLine`
17
-
17
+ - **The `DELETE /objects/accounts-payable/bill/{key}` endpoint**, via `IntacctRest::Endpoints::DeleteBill` and `IntacctRest::Delete` (the generic "delete this model" operation), sending only the model key
18
+ - **The `DELETE /objects/accounts-receivable/invoice/{key}` endpoint**, via `IntacctRest::Endpoints::DeleteInvoice` and `IntacctRest::Delete` (the generic "delete this model" operation), sending only the model key
18
19
  It has no Rails, ActiveRecord, or Redis dependency — the host application supplies its own token store and error-handling hook.
19
20
 
20
21
  ## Installation
@@ -245,14 +246,18 @@ What still raises, before any request is sent or when something is actually brok
245
246
 
246
247
  ```ruby
247
248
  validate :presence, %i[id name], on: :create
249
+
248
250
  validate :presence, %i[key], on: :update
249
251
  validate :kind_of, :string, %i[key], on: :update
250
252
 
253
+ validate :presence, %i[key], on: :delete
254
+ validate :kind_of, :string, %i[key], on: :delete
255
+
251
256
  validate :kind_of, :string, %i[id name status state ...]
252
257
  validate :inclusion, BANK_FILE_COUNTRY_CODES, %i[bank_files_payment_country_code]
253
258
  ```
254
259
 
255
- `on:` scopes a validation to one operation: it only runs when `#errors`/`#valid?` is called with that context. A validation without `on:` always runs. `Post` validates with `:create` and `Patch` with `:update`, so a vendor needs `id`/`name` to be created and `key` to be updated (see Updating a vendor, below).
260
+ `on:` scopes a validation to one operation: it only runs when `#errors`/`#valid?` is called with that context. A validation without `on:` always runs. `Post` validates with `:create`, `Patch` with `:update` and `Delete` with `:delete`. Therefore a vendor needs `id`/`name` to be created and `key` to be updated (see Updating a vendor, below) and a bill or invoices to be deleted needs `key`.
256
261
 
257
262
  Four validator kinds ship in `IntacctRest::Validators`:
258
263
 
@@ -261,7 +266,7 @@ Four validator kinds ship in `IntacctRest::Validators`:
261
266
  - `:inclusion` — the attribute, if present, must be included in a given list (e.g. Intacct's documented bank-file country codes)
262
267
  - `:custom` — the attribute, if present, is passed to an instance method you name (`record.send(method_name, value)`); a falsy return means invalid
263
268
 
264
- By default, `Post` validates the model first, raising `IntacctRest::ValidationError` and skipping the HTTP request entirely if it's invalid — currently that means `id`/`name` presence, every field's documented type, and `bank_files["paymentCountryCode"]` (if set) matching a real country code. `Patch` does the same with `key` in place of `id`/`name`. Note Intacct can auto-generate `id` when document sequencing is enabled for your company; override `errors` in a `Model::Vendor` subclass if you need to relax that.
269
+ By default, `Post` validates the model first, raising `IntacctRest::ValidationError` and skipping the HTTP request entirely if it's invalid — currently that means `id`/`name` presence, every field's documented type, and `bank_files["paymentCountryCode"]` (if set) matching a real country code. `Patch` and `Delete` does the same with `key` in place of `id`/`name`. Note Intacct can auto-generate `id` when document sequencing is enabled for your company; override `errors` in a `Model::Vendor` subclass if you need to relax that.
265
270
 
266
271
  ### Custom fields
267
272
 
@@ -327,6 +332,52 @@ vendor.id # => "V-00014" (filled in from the response by Patch, via mode
327
332
 
328
333
  Like `Post`, it never raises for the HTTP outcome and always returns an `IntacctRest::Result` (see The Result, above).
329
334
 
335
+ ## Deleting a payment
336
+
337
+ `IntacctRest::Endpoints::DeletePayment` sends `PATCH /objects/accounts-payable/bill/{key}`. Set `key` to pick the record, plus only the fields you want to change:
338
+
339
+ ```ruby
340
+ bill = IntacctRest::Model::Bill.new(key: "111")
341
+
342
+ result = IntacctRest::Endpoints::DeleteBill.call(bill: bill)
343
+
344
+ result.success? # => true
345
+ bill.id # => "00014" (model contains the same data before it was sent)
346
+ bill.key # => "111"
347
+ ```
348
+
349
+ - `key` is required on delete and must be a String.
350
+ - `results:` a successful response is a non content http response with 200 status
351
+
352
+
353
+ ## Deleting a invoice
354
+
355
+ `IntacctRest::Endpoints::DeleteInvoice` sends `PATCH /objects/accounts-receivable/invoice/{key}`. Set `key` to pick the record, plus only the fields you want to change:
356
+
357
+ ```ruby
358
+ invoice = IntacctRest::Model::Invoice.new(key: "111")
359
+
360
+ result = IntacctRest::Endpoints::DeleteInvoice.call(invoice: invoice)
361
+
362
+ result.success? # => true
363
+ invoice.id # => "00014" (model contains the same data before it was sent)
364
+ invoice.key # => "111"
365
+ ```
366
+
367
+ - `key` is required on delete and must be a String.
368
+ - `results:` a successful response is a non content http response with 200 status
369
+
370
+ ## IntacctRest::Delete
371
+
372
+ `IntacctRest::Delete` is the generic "delete this model" operation behind `DeleteBill` and `DeleteInvoice`, the DELETE counterpart of `Post`. It works against any model that responds to:
373
+
374
+ - `#intacct_object` — the collection path; `Delete` appends `/#{model.key}`
375
+ - `#key` — the record to delete
376
+ - `#errors(:delete)` — validated first the key that any model should required presense of; any error raises `IntacctRest::ValidationError` and no request is sent
377
+ - `#apply_result` — called with the Result on success but this is always empty model preserves its data
378
+
379
+ Like `Post`, it never raises for the HTTP outcome and always returns an `IntacctRest::Result` (see The Result, above).
380
+
330
381
  ## Creating an invoice
331
382
 
332
383
  Same three pieces as vendors — `IntacctRest::Model::Invoice` (data + validation), `IntacctRest::Post` (generic send), `IntacctRest::Endpoints::CreateInvoice` (the invoice-specific use case):
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IntacctRest
4
+ # Generic operation for Delete-ing (deleting) any model that responds to
5
+ # #intacct_object (the collection path), #key (the record appended to
6
+ # it)and #valid?/#errors with an :delete context. Raises
7
+ # IntacctRest::ValidationError if the model is invalid for delete.
8
+ # Returns an IntacctRest::Result (Success or Error) — never raises for the HTTP
9
+ # outcome itself. On success, calls model.apply_result(result) so the
10
+ # model can absorb whatever it cares about from the response.
11
+ class Delete
12
+ include AuthenticatedRequest
13
+
14
+ def self.call(model, config: IntacctRest.configuration, token_provider: nil)
15
+ new(config: config, token_provider: token_provider).send(:perform, model)
16
+ end
17
+
18
+ def initialize(config: IntacctRest.configuration, token_provider: nil)
19
+ @config = config
20
+ @token_provider = token_provider || IntacctRest::OauthClient.new(config: config)
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :config, :token_provider
26
+
27
+ def perform(model)
28
+ errors = model.errors(:delete)
29
+ raise IntacctRest::ValidationError.new(errors.join('; '), attributes: errors) unless errors.empty?
30
+
31
+ path = "#{model.intacct_object}/#{model.key}"
32
+ response = authenticated_response(:delete, path)
33
+ parsed = parse_json(response.body, path)
34
+ result = build_result(model, response, parsed)
35
+ model.apply_result(result) if result.success?
36
+ result
37
+ end
38
+
39
+ def build_result(model, response, parsed)
40
+ klass = response.is_a?(Net::HTTPSuccess) ? IntacctRest::Result::Success : IntacctRest::Result::Error
41
+ klass.new(model: model, code: response.code, body: parsed, headers: response.to_hash)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IntacctRest
4
+ module Endpoints
5
+ # Delete /objects/accounts-payable/delete/{key}. delete.key picks the
6
+ # record; only the key field is required and sent.
7
+
8
+ class DeleteBill
9
+ # model already knows the bill data it just checks http response.
10
+ def self.call(bill:, results: [], config: IntacctRest.configuration, token_provider: nil)
11
+ unless bill.is_a?(IntacctRest::Model::Bill)
12
+ raise ArgumentError, 'bill must be an IntacctRest::Model::Bill'
13
+ end
14
+
15
+ result = IntacctRest::Delete.call(bill, config: config, token_provider: token_provider)
16
+
17
+ result
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IntacctRest
4
+ module Endpoints
5
+ # Delete /objects/accounts-payable/delete/{key}. delete.key picks the
6
+ # record; only the key field is required and sent.
7
+
8
+ class DeleteInvoice
9
+ # model already knows the invoice data it just checks http response.
10
+ def self.call(invoice:, results: [], config: IntacctRest.configuration, token_provider: nil)
11
+ unless invoice.is_a?(IntacctRest::Model::Invoice)
12
+ raise ArgumentError, 'invoice must be an IntacctRest::Model::Invoice'
13
+ end
14
+
15
+ result = IntacctRest::Delete.call(invoice, config: config, token_provider: token_provider)
16
+
17
+ result
18
+ end
19
+ end
20
+ end
21
+ end
@@ -38,19 +38,22 @@ module IntacctRest
38
38
  attr_accessor(*READONLY_ATTRIBUTES)
39
39
  attr_reader :custom_fields
40
40
 
41
- validate :presence, %i[due_date created_date]
41
+ validate :presence, %i[due_date created_date], on: :create
42
42
 
43
43
  validate :kind_of, :string, %i[
44
44
  bill_number state reference_number description posting_date discount_cut_off_date
45
45
  due_date recommended_payment_date created_date invoice_type invoice_mode
46
- ]
47
- validate :kind_of, :boolean, %i[is_on_hold is_tax_inclusive]
46
+ ], on: :create
47
+ validate :kind_of, :boolean, %i[is_on_hold is_tax_inclusive], on: :create
48
48
  validate :kind_of, :hash, %i[
49
49
  vendor term contacts currency tax_solution bill_summary bill_back_template attachment
50
50
  dispute refuse
51
51
  ]
52
52
  validate :kind_of, :array, %i[lines]
53
53
 
54
+ validate :presence, %i[key], on: :delete
55
+ validate :kind_of, :string, %i[key], on: :delete
56
+
54
57
  # source: an arbitrary domain object (ActiveRecord record, OpenStruct,
55
58
  # another Model::Bill, ...) to pull matching attributes off of via
56
59
  # duck-typing — any WRITABLE_ATTRIBUTES/READONLY_ATTRIBUTES key it
@@ -40,8 +40,10 @@ module IntacctRest
40
40
  attr_accessor(*READONLY_ATTRIBUTES)
41
41
  attr_reader :custom_fields
42
42
 
43
- validate :presence, %i[invoice_date due_date]
43
+ validate :presence, %i[invoice_date due_date], on: :create
44
+ validate :presence, %i[key], on: :delete
44
45
 
46
+ validate :kind_of, :string, %i[key], on: :delete
45
47
  validate :kind_of, :string, %i[
46
48
  invoice_number state reference_number description invoice_date due_date
47
49
  invoice_type invoice_mode
@@ -52,6 +54,8 @@ module IntacctRest
52
54
  ]
53
55
  validate :kind_of, :array, %i[lines]
54
56
 
57
+
58
+
55
59
  # source: an arbitrary domain object (ActiveRecord record, OpenStruct,
56
60
  # another Model::Invoice, ...) to pull matching attributes off of via
57
61
  # duck-typing — any WRITABLE_ATTRIBUTES/READONLY_ATTRIBUTES key it
@@ -1,3 +1,3 @@
1
1
  module IntacctRest
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
data/lib/intacct_rest.rb CHANGED
@@ -42,6 +42,7 @@ require 'intacct_rest/result/success'
42
42
  require 'intacct_rest/result/error'
43
43
  require 'intacct_rest/post'
44
44
  require 'intacct_rest/patch'
45
+ require 'intacct_rest/delete'
45
46
  require 'intacct_rest/endpoints/create_vendor'
46
47
  require 'intacct_rest/endpoints/update_vendor'
47
48
  require 'intacct_rest/endpoints/create_invoice'
@@ -50,6 +51,8 @@ require 'intacct_rest/endpoints/create_invoice_line'
50
51
  require 'intacct_rest/endpoints/create_customer'
51
52
  require 'intacct_rest/endpoints/create_bill'
52
53
  require 'intacct_rest/endpoints/create_bill_line'
54
+ require 'intacct_rest/endpoints/delete_bill'
55
+ require 'intacct_rest/endpoints/delete_invoice'
53
56
  require 'intacct_rest/query'
54
57
  require 'intacct_rest/objects'
55
58
  require 'intacct_rest/schema_generator'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intacct-rest
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
  - Bernardo Espinoza
@@ -84,6 +84,7 @@ files:
84
84
  - lib/intacct_rest/client.rb
85
85
  - lib/intacct_rest/configuration.rb
86
86
  - lib/intacct_rest/custom_field.rb
87
+ - lib/intacct_rest/delete.rb
87
88
  - lib/intacct_rest/endpoints/create_bill.rb
88
89
  - lib/intacct_rest/endpoints/create_bill_line.rb
89
90
  - lib/intacct_rest/endpoints/create_customer.rb
@@ -91,6 +92,8 @@ files:
91
92
  - lib/intacct_rest/endpoints/create_invoice_line.rb
92
93
  - lib/intacct_rest/endpoints/create_term.rb
93
94
  - lib/intacct_rest/endpoints/create_vendor.rb
95
+ - lib/intacct_rest/endpoints/delete_bill.rb
96
+ - lib/intacct_rest/endpoints/delete_invoice.rb
94
97
  - lib/intacct_rest/endpoints/update_vendor.rb
95
98
  - lib/intacct_rest/error_reporting.rb
96
99
  - lib/intacct_rest/errors.rb
@@ -146,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
149
  - !ruby/object:Gem::Version
147
150
  version: '0'
148
151
  requirements: []
149
- rubygems_version: 4.0.20
152
+ rubygems_version: 4.0.6
150
153
  specification_version: 4
151
154
  summary: A Ruby wrapper for Intacct SAGE Rest API
152
155
  test_files: []