ledger_sync 1.3.3 → 1.3.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rubocop_todo.yml +0 -3
  4. data/Gemfile.lock +47 -44
  5. data/ledger_sync.gemspec +1 -1
  6. data/lib/ledger_sync.rb +5 -0
  7. data/lib/ledger_sync/adaptors/adaptor.rb +28 -0
  8. data/lib/ledger_sync/adaptors/netsuite/account/operations/create.rb +1 -1
  9. data/lib/ledger_sync/adaptors/netsuite/account/searcher.rb +0 -16
  10. data/lib/ledger_sync/adaptors/netsuite/adaptor.rb +11 -3
  11. data/lib/ledger_sync/adaptors/netsuite/currency/operations/create.rb +1 -1
  12. data/lib/ledger_sync/adaptors/netsuite/customer/operations/create.rb +1 -1
  13. data/lib/ledger_sync/adaptors/netsuite/department/ledger_serializer.rb +17 -0
  14. data/lib/ledger_sync/adaptors/netsuite/department/operations/create.rb +25 -0
  15. data/lib/ledger_sync/adaptors/netsuite/department/operations/delete.rb +25 -0
  16. data/lib/ledger_sync/adaptors/netsuite/department/operations/find.rb +25 -0
  17. data/lib/ledger_sync/adaptors/netsuite/department/operations/update.rb +25 -0
  18. data/lib/ledger_sync/adaptors/netsuite/department/searcher.rb +12 -0
  19. data/lib/ledger_sync/adaptors/netsuite/ledger_serializer.rb +1 -1
  20. data/lib/ledger_sync/adaptors/netsuite/record/http_method.rb +14 -19
  21. data/lib/ledger_sync/adaptors/netsuite/record/metadata.rb +47 -21
  22. data/lib/ledger_sync/adaptors/netsuite/record/parameter.rb +20 -0
  23. data/lib/ledger_sync/adaptors/netsuite/record/property.rb +8 -31
  24. data/lib/ledger_sync/adaptors/netsuite/searcher.rb +19 -0
  25. data/lib/ledger_sync/adaptors/netsuite/vendor/operations/create.rb +1 -1
  26. data/lib/ledger_sync/adaptors/quickbooks_online/adaptor.rb +6 -11
  27. data/lib/ledger_sync/adaptors/quickbooks_online/bill_payment/ledger_serializer.rb +76 -0
  28. data/lib/ledger_sync/adaptors/quickbooks_online/bill_payment/operations/create.rb +33 -0
  29. data/lib/ledger_sync/adaptors/quickbooks_online/bill_payment/operations/find.rb +33 -0
  30. data/lib/ledger_sync/adaptors/quickbooks_online/bill_payment/operations/update.rb +33 -0
  31. data/lib/ledger_sync/adaptors/quickbooks_online/bill_payment_line_item/ledger_serializer.rb +19 -0
  32. data/lib/ledger_sync/adaptors/quickbooks_online/operation.rb +1 -1
  33. data/lib/ledger_sync/adaptors/quickbooks_online/operation/find.rb +0 -6
  34. data/lib/ledger_sync/adaptors/quickbooks_online/preferences/ledger_serializer.rb +45 -0
  35. data/lib/ledger_sync/adaptors/quickbooks_online/preferences/operations/find.rb +38 -0
  36. data/lib/ledger_sync/adaptors/quickbooks_online/resources/preferences.rb +24 -0
  37. data/lib/ledger_sync/adaptors/searcher.rb +4 -0
  38. data/lib/ledger_sync/error/operation_errors.rb +0 -10
  39. data/lib/ledger_sync/resource.rb +1 -1
  40. data/lib/ledger_sync/resources/bill_payment.rb +32 -0
  41. data/lib/ledger_sync/resources/bill_payment_line_item.rb +15 -0
  42. data/lib/ledger_sync/type/hash.rb +34 -0
  43. data/lib/ledger_sync/util/read_only_object.rb +54 -0
  44. data/lib/ledger_sync/version.rb +1 -1
  45. metadata +23 -30
  46. data/qa/env_spec.rb +0 -5
  47. data/qa/netsuite/account_spec.rb +0 -20
  48. data/qa/netsuite/currency_spec.rb +0 -16
  49. data/qa/netsuite/customer.rb +0 -76
  50. data/qa/netsuite/customer_spec.rb +0 -21
  51. data/qa/netsuite/vendor.rb +0 -76
  52. data/qa/netsuite/vendor_spec.rb +0 -23
  53. data/qa/netsuite_soap/customer_spec.rb +0 -21
  54. data/qa/netsuite_soap/subsidiary_spec.rb +0 -0
  55. data/qa/qa_helper.rb +0 -58
  56. data/qa/quickbooks_online/account_spec.rb +0 -14
  57. data/qa/quickbooks_online/customer_spec.rb +0 -13
  58. data/qa/quickbooks_online/expense_spec.rb +0 -31
  59. data/qa/quickbooks_online/vendor_spec.rb +0 -13
  60. data/qa/stripe/customers_spec.rb +0 -15
  61. data/qa/support/adaptor_helpers.rb +0 -99
  62. data/qa/support/adaptor_support_setup.rb +0 -23
  63. data/qa/support/netsuite_helpers.rb +0 -33
  64. data/qa/support/netsuite_shared_examples.rb +0 -30
  65. data/qa/support/netsuite_soap_helpers.rb +0 -33
  66. data/qa/support/netsuite_soap_shared_examples.rb +0 -10
  67. data/qa/support/quickbooks_online_helpers.rb +0 -42
  68. data/qa/support/quickbooks_online_shared_examples.rb +0 -82
  69. data/qa/support/shared_examples.rb +0 -127
  70. data/qa/support/stripe_helpers.rb +0 -22
  71. data/qa/support/stripe_shared_examples.rb +0 -10
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module Adaptors
5
+ module NetSuite
6
+ module Department
7
+ module Operations
8
+ class Find < NetSuite::Operation::Find
9
+ class Contract < LedgerSync::Adaptors::Contract
10
+ params do
11
+ required(:external_id).maybe(:string)
12
+ required(:ledger_id).filled(:string)
13
+ required(:name).maybe(:string)
14
+ optional(:active).maybe(:bool?)
15
+ optional(:sub_department).maybe(:bool?)
16
+ optional(:fully_qualified_name).maybe(:string)
17
+ optional(:parent).maybe(:hash, Types::Reference)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module Adaptors
5
+ module NetSuite
6
+ module Department
7
+ module Operations
8
+ class Update < NetSuite::Operation::Update
9
+ class Contract < LedgerSync::Adaptors::Contract
10
+ params do
11
+ required(:external_id).maybe(:string)
12
+ required(:ledger_id).filled(:string)
13
+ required(:name).filled(:string)
14
+ optional(:active).maybe(:bool?)
15
+ optional(:sub_department).maybe(:bool?)
16
+ optional(:fully_qualified_name).maybe(:string)
17
+ optional(:parent).maybe(:hash, Types::Reference)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module Adaptors
5
+ module NetSuite
6
+ module Department
7
+ class Searcher < Searcher
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -10,7 +10,7 @@ module LedgerSync
10
10
  def self.api_resource_path(resource: nil)
11
11
  raise 'Resource ledger_id is required to build API request path' if resource.present? && resource.ledger_id.blank?
12
12
 
13
- ret = "record/#{api_resource_type}"
13
+ ret = api_resource_type.to_s
14
14
  ret += "/#{resource.ledger_id}" if resource.present?
15
15
  ret
16
16
  end
@@ -7,28 +7,23 @@ module LedgerSync
7
7
  module Adaptors
8
8
  module NetSuite
9
9
  module Record
10
- class HTTPMethod
11
- attr_reader :method,
12
- :parameters,
13
- :path,
14
- :raw,
15
- :summary
10
+ class HTTPMethod < Util::ReadOnlyObject
11
+ attribute :key
12
+ attribute :method
13
+ attribute :path
14
+ attribute :summary
16
15
 
17
- def initialize(method:, parameters:, path:, raw:, summary:)
18
- @method = method
19
- @parameters = parameters
20
- @path = path
21
- @raw = raw
22
- @summary = summary
16
+ def initialize(args = {})
17
+ super(
18
+ args.merge(
19
+ key: "#{method} #{path}".downcase
20
+ )
21
+ )
23
22
  end
24
23
 
25
- def self.new_from_hash(data:, method:, path:)
26
- new(
27
- method: method,
28
- parameters: data['parameters'],
29
- path: path,
30
- raw: data,
31
- summary: data['summary']
24
+ def parameters
25
+ Parameter.new_from_array(
26
+ raw[:parameters]
32
27
  )
33
28
  end
34
29
  end
@@ -10,7 +10,7 @@ module LedgerSync
10
10
  # - record properties/attributes
11
11
  #
12
12
  class Metadata
13
- BASE_PATH = 'metadata-catalog/record'
13
+ BASE_PATH = 'metadata-catalog'
14
14
 
15
15
  attr_reader :adaptor,
16
16
  :record
@@ -20,16 +20,29 @@ module LedgerSync
20
20
  @record = record
21
21
  end
22
22
 
23
+ def create
24
+ @create ||= http_methods.find { |_e| "post /#{record}" }
25
+ end
26
+
27
+ def delete
28
+ @delete ||= http_methods.find { |_e| "delete /#{record}/{id}" }
29
+ end
30
+
31
+ def find
32
+ @find ||= show
33
+ end
34
+
23
35
  def http_methods
24
36
  @http_methods ||= begin
25
37
  ret = []
26
38
 
27
- http_methods_response.body['paths'].each do |path, path_data|
39
+ metadata_response.body['paths'].each do |path, path_data|
28
40
  path_data.each do |method, method_data|
29
41
  ret << HTTPMethod.new_from_hash(
30
- data: method_data,
31
- method: method,
32
- path: path
42
+ method_data.merge(
43
+ method: method,
44
+ path: path
45
+ )
33
46
  )
34
47
  end
35
48
  end
@@ -38,8 +51,8 @@ module LedgerSync
38
51
  end
39
52
  end
40
53
 
41
- def http_methods_response
42
- @http_methods_response = begin
54
+ def metadata_response
55
+ @metadata_response = begin
43
56
  adaptor.get(
44
57
  headers: {
45
58
  'Accept' => 'application/swagger+json'
@@ -50,23 +63,36 @@ module LedgerSync
50
63
  end
51
64
 
52
65
  def properties
53
- @properties = properties_response.body['properties'].map do |key, data|
54
- Property.new_from_hash(
55
- data: data,
56
- key: key
57
- )
66
+ @properties ||= begin
67
+ ret = []
68
+ props = metadata_response.body['components']['schemas'][record.to_s]['properties']
69
+ props.map do |key, prop|
70
+ next unless prop.key?('title')
71
+
72
+ ret << Property.new_from_hash(
73
+ prop.merge(
74
+ key: key
75
+ )
76
+ )
77
+ end
78
+ ret
58
79
  end
59
80
  end
60
81
 
61
- def properties_response
62
- @properties_response = begin
63
- adaptor.get(
64
- headers: {
65
- 'Accept' => 'application/swagger+json'
66
- },
67
- path: "#{BASE_PATH}/#{record}"
68
- )
69
- end
82
+ def index
83
+ @index ||= http_methods.find { |_e| "get /#{record}" }
84
+ end
85
+
86
+ def show
87
+ @show ||= http_methods.find { |_e| "get /#{record}/{id}" }
88
+ end
89
+
90
+ def update
91
+ @update ||= http_methods.find { |_e| "patch /#{record}/{id}" }
92
+ end
93
+
94
+ def upsert
95
+ @upsert ||= http_methods.find { |_e| "put /#{record}/{id}" }
70
96
  end
71
97
  end
72
98
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Parser for OpenAPI 3.0 data for a given record method
5
+ #
6
+ module LedgerSync
7
+ module Adaptors
8
+ module NetSuite
9
+ module Record
10
+ class Parameter < Util::ReadOnlyObject
11
+ attribute :description
12
+ attribute :location, source: :in
13
+ attribute :name
14
+ attribute :required
15
+ attribute :schema
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -7,37 +7,14 @@ module LedgerSync
7
7
  module Adaptors
8
8
  module NetSuite
9
9
  module Record
10
- class Property
11
- attr_reader :enum,
12
- :format,
13
- :key,
14
- :title,
15
- :type
16
-
17
- def initialize(
18
- enum: [],
19
- format: nil,
20
- key:,
21
- title:,
22
- type:
23
- )
24
-
25
- @enum = enum
26
- @format = format
27
- @key = key
28
- @title = title
29
- @type = type
30
- end
31
-
32
- def self.new_from_hash(data:, key:)
33
- new(
34
- enum: data['enum'],
35
- format: data['format'],
36
- key: key,
37
- title: data['title'],
38
- type: data['type']
39
- )
40
- end
10
+ class Property < Util::ReadOnlyObject
11
+ attribute :enum, default: nil
12
+ attribute :format, default: nil
13
+ attribute :key
14
+ attribute :nullable, default: false
15
+ attribute :read_only, default: false, source: :readOnly
16
+ attribute :title
17
+ attribute :type
41
18
  end
42
19
  end
43
20
  end
@@ -6,6 +6,25 @@ module LedgerSync
6
6
  class Searcher < Adaptors::Searcher
7
7
  include Mixins::OffsetAndLimitPaginationSearcherMixin
8
8
 
9
+ def resources
10
+ resource_class = self.class.inferred_resource_class
11
+
12
+ @resources ||= begin
13
+ @request = adaptor
14
+ .get(
15
+ path: "/#{adaptor.class.ledger_resource_type_for(resource_class: resource_class)}?limit=#{limit}&offset=#{offset}"
16
+ )
17
+
18
+ request.body
19
+ .fetch('items')
20
+ .map do |c|
21
+ ledger_deserializer_class.new(
22
+ resource: resource_class.new
23
+ ).deserialize(hash: c)
24
+ end
25
+ end
26
+ end
27
+
9
28
  private
10
29
 
11
30
  def default_offset
@@ -8,7 +8,7 @@ module LedgerSync
8
8
  class Create < NetSuite::Operation::Create
9
9
  class Contract < LedgerSync::Adaptors::Contract
10
10
  params do
11
- required(:external_id).maybe(:string)
11
+ required(:external_id).filled(:string)
12
12
  required(:ledger_id).value(:nil)
13
13
  required(:company_name).filled(:string)
14
14
  required(:display_name).filled(:string)
@@ -11,11 +11,6 @@ module LedgerSync
11
11
  ROOT_URI = 'https://quickbooks.api.intuit.com'
12
12
  REVOKE_TOKEN_URI = 'https://developer.api.intuit.com/v2/oauth2/tokens/revoke'
13
13
  ROOT_SANDBOX_URI = 'https://sandbox-quickbooks.api.intuit.com'
14
- API_RESOURCE_MAPPING_OVERRIDE = {
15
- LedgerSync::Expense => 'purchase',
16
- LedgerSync::LedgerClass => 'class'
17
- }
18
- API_RESOURCE_MAPPING_OVERRIDE_REVERSE = API_RESOURCE_MAPPING_OVERRIDE.invert
19
14
 
20
15
  attr_reader :access_token,
21
16
  :client_id,
@@ -184,8 +179,12 @@ module LedgerSync
184
179
  %i[access_token expires_at refresh_token refresh_token_expires_at]
185
180
  end
186
181
 
187
- def self.ledger_resource_type_for(resource_class:)
188
- API_RESOURCE_MAPPING_OVERRIDE[resource_class] || resource_class.resource_type.to_s
182
+ def self.ledger_resource_type_overrides
183
+ {
184
+ LedgerSync::Expense => 'purchase',
185
+ LedgerSync::LedgerClass => 'class',
186
+ LedgerSync::Adaptors::QuickBooksOnline::Preferences => 'preferences'
187
+ }
189
188
  end
190
189
 
191
190
  def self.new_from_env(**override)
@@ -218,10 +217,6 @@ module LedgerSync
218
217
  )
219
218
  end
220
219
 
221
- def self.resource_from_ledger_type(type:)
222
- API_RESOURCE_MAPPING_OVERRIDE_REVERSE[type.downcase] || LedgerSync.resources[type.downcase.to_sym]
223
- end
224
-
225
220
  private
226
221
 
227
222
  def oauth_base_uri
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../currency/ledger_serializer'
4
+ require_relative '../vendor/ledger_serializer'
5
+ require_relative '../department/ledger_serializer'
6
+ require_relative '../bill_payment_line_item/ledger_serializer'
7
+
8
+ module LedgerSync
9
+ module Adaptors
10
+ module QuickBooksOnline
11
+ module BillPayment
12
+ class LedgerSerializer < QuickBooksOnline::LedgerSerializer
13
+ id
14
+
15
+ attribute ledger_attribute: 'TotalAmt',
16
+ resource_attribute: :amount,
17
+ type: LedgerSerializerType::AmountType
18
+
19
+ references_one ledger_attribute: :CurrencyRef,
20
+ resource_attribute: :currency,
21
+ serializer: Currency::LedgerSerializer
22
+
23
+ attribute ledger_attribute: 'VendorRef.value',
24
+ resource_attribute: 'vendor.ledger_id'
25
+
26
+ attribute ledger_attribute: 'DepartmentRef.value',
27
+ resource_attribute: 'department.ledger_id'
28
+
29
+ attribute ledger_attribute: 'APAccountRef.value',
30
+ resource_attribute: 'account.ledger_id'
31
+
32
+ attribute ledger_attribute: 'DocNumber',
33
+ resource_attribute: :reference_number
34
+
35
+ attribute ledger_attribute: 'PrivateNote',
36
+ resource_attribute: :memo
37
+
38
+ attribute ledger_attribute: 'ExchangeRate',
39
+ resource_attribute: :exchange_rate
40
+
41
+ attribute ledger_attribute: 'TxnDate',
42
+ resource_attribute: :transaction_date,
43
+ type: LedgerSerializerType::DateType
44
+
45
+ attribute ledger_attribute: 'PayType',
46
+ resource_attribute: :payment_type,
47
+ type: LedgerSerializerType::PaymentType
48
+
49
+ attribute ledger_attribute: 'CreditCardPayment' do |res|
50
+ if res.credit_card_account
51
+ {
52
+ 'CCAccountRef' => {
53
+ 'value' => res.credit_card_account.ledger_id
54
+ }
55
+ }
56
+ end
57
+ end
58
+
59
+ attribute ledger_attribute: 'CheckPayment' do |res|
60
+ if res.bank_account
61
+ {
62
+ 'BankAccountRef' => {
63
+ 'value' => res.bank_account.ledger_id
64
+ }
65
+ }
66
+ end
67
+ end
68
+
69
+ references_many ledger_attribute: 'Line',
70
+ resource_attribute: :line_items,
71
+ serializer: BillPaymentLineItem::LedgerSerializer
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LedgerSync
4
+ module Adaptors
5
+ module QuickBooksOnline
6
+ module BillPayment
7
+ module Operations
8
+ class Create < Operation::Create
9
+ class Contract < LedgerSync::Adaptors::Contract
10
+ params do
11
+ required(:external_id).maybe(:string)
12
+ optional(:account).hash(Types::Reference)
13
+ required(:amount).filled(:integer)
14
+ optional(:bank_account).maybe(Types::Reference)
15
+ optional(:credit_card_account).maybe(Types::Reference)
16
+ required(:currency).filled(:hash, Types::Reference)
17
+ required(:department).hash(Types::Reference)
18
+ optional(:exchange_rate).maybe(:float)
19
+ required(:ledger_id).value(:nil)
20
+ required(:line_items).array(Types::Reference)
21
+ optional(:memo).filled(:string)
22
+ required(:payment_type).filled(:string)
23
+ optional(:reference_number).maybe(:string)
24
+ optional(:transaction_date).filled(:date?)
25
+ required(:vendor).hash(Types::Reference)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end