ledger_sync 1.0.10 → 1.1.1

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +36 -20
  3. data/README.md +105 -66
  4. data/ledger_sync.gemspec +1 -0
  5. data/lib/ledger_sync.rb +23 -4
  6. data/lib/ledger_sync/adaptors/operation.rb +28 -28
  7. data/lib/ledger_sync/adaptors/quickbooks_online/account/mapping.rb +325 -0
  8. data/lib/ledger_sync/adaptors/quickbooks_online/account/operations/create.rb +54 -0
  9. data/lib/ledger_sync/adaptors/quickbooks_online/account/operations/find.rb +38 -0
  10. data/lib/ledger_sync/adaptors/quickbooks_online/account/operations/update.rb +61 -0
  11. data/lib/ledger_sync/adaptors/quickbooks_online/account/searcher.rb +67 -0
  12. data/lib/ledger_sync/adaptors/quickbooks_online/adaptor.rb +18 -16
  13. data/lib/ledger_sync/adaptors/quickbooks_online/bill/operations/create.rb +65 -0
  14. data/lib/ledger_sync/adaptors/quickbooks_online/bill/operations/find.rb +37 -0
  15. data/lib/ledger_sync/adaptors/quickbooks_online/bill/operations/update.rb +69 -0
  16. data/lib/ledger_sync/adaptors/quickbooks_online/bill/searcher.rb +28 -0
  17. data/lib/ledger_sync/adaptors/quickbooks_online/customer/operations/create.rb +6 -6
  18. data/lib/ledger_sync/adaptors/quickbooks_online/customer/operations/find.rb +1 -3
  19. data/lib/ledger_sync/adaptors/quickbooks_online/customer/operations/update.rb +6 -9
  20. data/lib/ledger_sync/adaptors/quickbooks_online/customer/searcher.rb +2 -38
  21. data/lib/ledger_sync/adaptors/quickbooks_online/deposit/operations/create.rb +61 -0
  22. data/lib/ledger_sync/adaptors/quickbooks_online/deposit/operations/find.rb +36 -0
  23. data/lib/ledger_sync/adaptors/quickbooks_online/deposit/operations/update.rb +65 -0
  24. data/lib/ledger_sync/adaptors/quickbooks_online/deposit/searcher.rb +28 -0
  25. data/lib/ledger_sync/adaptors/quickbooks_online/expense/mapping.rb +15 -0
  26. data/lib/ledger_sync/adaptors/quickbooks_online/expense/operations/create.rb +68 -0
  27. data/lib/ledger_sync/adaptors/quickbooks_online/expense/operations/find.rb +39 -0
  28. data/lib/ledger_sync/adaptors/quickbooks_online/expense/operations/update.rb +72 -0
  29. data/lib/ledger_sync/adaptors/quickbooks_online/expense/searcher.rb +28 -0
  30. data/lib/ledger_sync/adaptors/quickbooks_online/journal_entry/mapping.rb +14 -0
  31. data/lib/ledger_sync/adaptors/quickbooks_online/journal_entry/operations/create.rb +56 -0
  32. data/lib/ledger_sync/adaptors/quickbooks_online/journal_entry/operations/find.rb +34 -0
  33. data/lib/ledger_sync/adaptors/quickbooks_online/journal_entry/operations/update.rb +60 -0
  34. data/lib/ledger_sync/adaptors/quickbooks_online/journal_entry/searcher.rb +28 -0
  35. data/lib/ledger_sync/adaptors/quickbooks_online/operation.rb +30 -0
  36. data/lib/ledger_sync/adaptors/quickbooks_online/payment/operations/create.rb +8 -22
  37. data/lib/ledger_sync/adaptors/quickbooks_online/payment/operations/find.rb +0 -2
  38. data/lib/ledger_sync/adaptors/quickbooks_online/payment/operations/update.rb +6 -22
  39. data/lib/ledger_sync/adaptors/quickbooks_online/searcher.rb +45 -0
  40. data/lib/ledger_sync/adaptors/quickbooks_online/transfer/operations/create.rb +52 -0
  41. data/lib/ledger_sync/adaptors/quickbooks_online/transfer/operations/find.rb +36 -0
  42. data/lib/ledger_sync/adaptors/quickbooks_online/transfer/operations/update.rb +57 -0
  43. data/lib/ledger_sync/adaptors/quickbooks_online/vendor/operations/create.rb +46 -0
  44. data/lib/ledger_sync/adaptors/quickbooks_online/vendor/operations/find.rb +36 -0
  45. data/lib/ledger_sync/adaptors/quickbooks_online/vendor/operations/update.rb +51 -0
  46. data/lib/ledger_sync/adaptors/quickbooks_online/vendor/searcher.rb +64 -0
  47. data/lib/ledger_sync/adaptors/searcher.rb +3 -1
  48. data/lib/ledger_sync/adaptors/test/account/operations/create.rb +53 -0
  49. data/lib/ledger_sync/adaptors/test/account/operations/find.rb +38 -0
  50. data/lib/ledger_sync/adaptors/test/account/operations/invalid.rb +25 -0
  51. data/lib/ledger_sync/adaptors/test/account/operations/update.rb +50 -0
  52. data/lib/ledger_sync/adaptors/test/account/operations/valid.rb +31 -0
  53. data/lib/ledger_sync/adaptors/test/account/searcher.rb +40 -0
  54. data/lib/ledger_sync/adaptors/test/adaptor.rb +4 -4
  55. data/lib/ledger_sync/adaptors/test/customer/operations/create.rb +4 -6
  56. data/lib/ledger_sync/adaptors/test/customer/operations/find.rb +0 -2
  57. data/lib/ledger_sync/adaptors/test/customer/operations/update.rb +4 -6
  58. data/lib/ledger_sync/adaptors/test/customer/searcher.rb +2 -2
  59. data/lib/ledger_sync/adaptors/test/expense/operations/create.rb +54 -0
  60. data/lib/ledger_sync/adaptors/test/expense/operations/find.rb +39 -0
  61. data/lib/ledger_sync/adaptors/test/expense/operations/update.rb +57 -0
  62. data/lib/ledger_sync/adaptors/test/payment/operations/create.rb +4 -20
  63. data/lib/ledger_sync/adaptors/test/payment/operations/find.rb +0 -2
  64. data/lib/ledger_sync/adaptors/test/payment/operations/update.rb +4 -20
  65. data/lib/ledger_sync/adaptors/test/transfer/operations/create.rb +45 -0
  66. data/lib/ledger_sync/adaptors/test/transfer/operations/find.rb +36 -0
  67. data/lib/ledger_sync/adaptors/test/transfer/operations/update.rb +48 -0
  68. data/lib/ledger_sync/adaptors/test/vendor/operations/create.rb +47 -0
  69. data/lib/ledger_sync/adaptors/test/vendor/operations/find.rb +34 -0
  70. data/lib/ledger_sync/adaptors/test/vendor/operations/invalid.rb +21 -0
  71. data/lib/ledger_sync/adaptors/test/vendor/operations/update.rb +44 -0
  72. data/lib/ledger_sync/adaptors/test/vendor/operations/valid.rb +27 -0
  73. data/lib/ledger_sync/adaptors/test/vendor/searcher.rb +41 -0
  74. data/lib/ledger_sync/error/resource_errors.rb +24 -0
  75. data/lib/ledger_sync/resource.rb +24 -64
  76. data/lib/ledger_sync/resource_attribute.rb +50 -0
  77. data/lib/ledger_sync/resource_attribute/dirty_mixin.rb +49 -0
  78. data/lib/ledger_sync/resource_attribute/mixin.rb +90 -0
  79. data/lib/ledger_sync/resource_attribute/reference.rb +9 -0
  80. data/lib/ledger_sync/resource_attribute/reference/many.rb +34 -0
  81. data/lib/ledger_sync/resource_attribute/reference/one.rb +33 -0
  82. data/lib/ledger_sync/resource_attribute_set.rb +58 -0
  83. data/lib/ledger_sync/resources/account.rb +14 -0
  84. data/lib/ledger_sync/resources/bill.rb +17 -0
  85. data/lib/ledger_sync/resources/bill_line_item.rb +11 -0
  86. data/lib/ledger_sync/resources/customer.rb +5 -4
  87. data/lib/ledger_sync/resources/deposit.rb +16 -0
  88. data/lib/ledger_sync/resources/deposit_line_item.rb +11 -0
  89. data/lib/ledger_sync/resources/expense.rb +19 -0
  90. data/lib/ledger_sync/resources/expense_line_item.rb +11 -0
  91. data/lib/ledger_sync/resources/journal_entry.rb +13 -0
  92. data/lib/ledger_sync/resources/journal_entry_line_item.rb +12 -0
  93. data/lib/ledger_sync/resources/payment.rb +5 -3
  94. data/lib/ledger_sync/resources/transfer.rb +15 -0
  95. data/lib/ledger_sync/resources/vendor.rb +12 -0
  96. data/lib/ledger_sync/result.rb +0 -24
  97. data/lib/ledger_sync/type/boolean.rb +17 -0
  98. data/lib/ledger_sync/type/date.rb +17 -0
  99. data/lib/ledger_sync/type/float.rb +17 -0
  100. data/lib/ledger_sync/type/integer.rb +17 -0
  101. data/lib/ledger_sync/type/reference_many.rb +27 -0
  102. data/lib/ledger_sync/type/reference_one.rb +26 -0
  103. data/lib/ledger_sync/type/string.rb +17 -0
  104. data/lib/ledger_sync/type/value.rb +12 -0
  105. data/lib/ledger_sync/type/value_mixin.rb +19 -0
  106. data/lib/ledger_sync/util/hash_helpers.rb +16 -1
  107. data/lib/ledger_sync/util/resources_builder.rb +36 -9
  108. data/lib/ledger_sync/version.rb +1 -1
  109. metadata +92 -7
  110. data/lib/ledger_sync/adaptors/quickbooks_online/customer/operations/upsert.rb +0 -42
  111. data/lib/ledger_sync/adaptors/quickbooks_online/payment/operations/upsert.rb +0 -53
  112. data/lib/ledger_sync/adaptors/test/customer/operations/upsert.rb +0 -42
  113. data/lib/ledger_sync/adaptors/test/payment/operations/upsert.rb +0 -53
  114. data/lib/ledger_sync/sync.rb +0 -108
  115. data/lib/ledger_sync/util/coordinator.rb +0 -72
@@ -16,7 +16,7 @@ module LedgerSync
16
16
  private
17
17
 
18
18
  def operate
19
- response = adaptor.upsert(
19
+ response = adaptor.post(
20
20
  resource: 'customer',
21
21
  payload: local_resource_data
22
22
  )
@@ -27,12 +27,12 @@ module LedgerSync
27
27
 
28
28
  def local_resource_data
29
29
  {
30
- 'DisplayName': resource.name,
31
- "PrimaryPhone": {
32
- "FreeFormNumber": resource.phone_number
30
+ 'DisplayName' => resource.name,
31
+ 'PrimaryPhone' => {
32
+ 'FreeFormNumber' => resource.phone_number
33
33
  },
34
- "PrimaryEmailAddr": {
35
- "Address": resource.email
34
+ 'PrimaryEmailAddr' => {
35
+ 'Address' => resource.email
36
36
  }
37
37
  }
38
38
  end
@@ -18,14 +18,12 @@ module LedgerSync
18
18
  def operate
19
19
  return failure(nil) if resource.ledger_id.nil?
20
20
 
21
- response = @adaptor.find(
21
+ response = adaptor.find(
22
22
  resource: 'customer',
23
23
  id: resource.ledger_id
24
24
  )
25
25
 
26
26
  success(response: response)
27
- rescue OAuth2::Error => e
28
- failure(e)
29
27
  end
30
28
  end
31
29
  end
@@ -22,26 +22,23 @@ module LedgerSync
22
22
  resource: 'customer',
23
23
  id: resource.ledger_id
24
24
  )
25
-
26
- response = adaptor.upsert(
25
+ response = adaptor.post(
27
26
  resource: 'customer',
28
27
  payload: merge_into(from: local_resource_data, to: ledger_resource_data)
29
28
  )
30
29
 
31
30
  resource.ledger_id = response.dig('Id')
32
31
  success(response: response)
33
- rescue OAuth2::Error => e
34
- failure(e)
35
32
  end
36
33
 
37
34
  def local_resource_data
38
35
  {
39
- 'DisplayName': resource.name,
40
- "PrimaryPhone": {
41
- "FreeFormNumber": resource.phone_number
36
+ 'DisplayName' => resource.name,
37
+ "PrimaryPhone" => {
38
+ "FreeFormNumber" => resource.phone_number
42
39
  },
43
- "PrimaryEmailAddr": {
44
- "Address": resource.email
40
+ "PrimaryEmailAddr" => {
41
+ "Address" => resource.email
45
42
  }
46
43
  }
47
44
  end
@@ -2,17 +2,7 @@ module LedgerSync
2
2
  module Adaptors
3
3
  module QuickBooksOnline
4
4
  module Customer
5
- class Searcher < LedgerSync::Adaptors::Searcher
6
- def next_searcher
7
- paginate(limit: limit, offset: offset + limit)
8
- end
9
-
10
- def previous_searcher
11
- return nil if offset <= 1
12
-
13
- paginate(limit: limit, offset: offset - limit)
14
- end
15
-
5
+ class Searcher < LedgerSync::Adaptors::QuickBooksOnline::Searcher
16
6
  def resources
17
7
  @resources ||= begin
18
8
  adaptor
@@ -25,37 +15,11 @@ module LedgerSync
25
15
  .map do |c|
26
16
  LedgerSync::Customer.new(
27
17
  ledger_id: c.fetch('Id'),
28
- name: c.dig('FullyQualifiedName'),
29
- # active: c.dig('Active')
18
+ name: c.dig('FullyQualifiedName')
30
19
  )
31
20
  end
32
21
  end
33
22
  end
34
-
35
- def search
36
- super
37
- rescue OAuth2::Error => e
38
- @response = e # TODO: Better catch/raise errors as LedgerSync::Error
39
- failure
40
- end
41
-
42
- private
43
- # Pagination uses notation of limit and offset
44
- # limit: number of results per page
45
- #
46
- # offset: position of first result in a list.
47
- # starts from 1, not 0
48
- #
49
- # More here:
50
- # https://developer.intuit.com/app/developer/qbo/docs/develop/explore-the-quickbooks-online-api/data-queries#pagination
51
-
52
- def limit
53
- pagination.fetch(:limit, 10).to_i
54
- end
55
-
56
- def offset
57
- pagination.fetch(:offset, 1).to_i
58
- end
59
23
  end
60
24
  end
61
25
  end
@@ -0,0 +1,61 @@
1
+ module LedgerSync
2
+ module Adaptors
3
+ module QuickBooksOnline
4
+ module Deposit
5
+ module Operations
6
+ class Create < Operation::Create
7
+ class Contract < LedgerSync::Adaptors::Contract
8
+ params do
9
+ required(:ledger_id).value(:nil)
10
+ required(:account).hash(Types::Reference)
11
+ required(:currency).filled(:string)
12
+ required(:memo).filled(:string)
13
+ required(:transaction_date).filled(:date?)
14
+ required(:exchange_rate).maybe(:float)
15
+ required(:line_items).array(Types::Reference)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def operate
22
+ response = adaptor.post(
23
+ resource: 'deposit',
24
+ payload: local_resource_data
25
+ )
26
+
27
+ resource.ledger_id = response.dig('Id')
28
+ success(response: response)
29
+ end
30
+
31
+ def local_resource_data
32
+ {
33
+ 'CurrencyRef' => {
34
+ 'value' => resource.currency,
35
+ },
36
+ 'TxnDate' => resource.transaction_date.to_s, # Format: YYYY-MM-DD
37
+ 'PrivateNote' => resource.memo,
38
+ 'ExchangeRate' => resource.exchange_rate,
39
+ 'DepositToAccountRef' => {
40
+ 'value' => resource.account.ledger_id
41
+ },
42
+ 'Line' => resource.line_items.map do |line_item|
43
+ {
44
+ 'DetailType' => 'DepositLineDetail',
45
+ 'DepositLineDetail' => {
46
+ 'AccountRef' => {
47
+ 'value' => line_item.account&.ledger_id
48
+ }
49
+ },
50
+ 'Amount' => line_item.amount / 100.0,
51
+ 'Description' => line_item.description
52
+ }
53
+ end
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,36 @@
1
+ module LedgerSync
2
+ module Adaptors
3
+ module QuickBooksOnline
4
+ module Deposit
5
+ module Operations
6
+ class Find < Operation::Find
7
+ class Contract < LedgerSync::Adaptors::Contract
8
+ schema do
9
+ required(:ledger_id).filled(:string)
10
+ required(:account).hash(Types::Reference)
11
+ required(:currency).maybe(:string)
12
+ required(:memo).maybe(:string)
13
+ required(:transaction_date).filled(:date?)
14
+ required(:exchange_rate).maybe(:float)
15
+ required(:line_items).array(Types::Reference)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def operate
22
+ return failure(nil) if resource.ledger_id.nil?
23
+
24
+ response = adaptor.find(
25
+ resource: 'deposit',
26
+ id: resource.ledger_id
27
+ )
28
+
29
+ success(response: response)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ module LedgerSync
2
+ module Adaptors
3
+ module QuickBooksOnline
4
+ module Deposit
5
+ module Operations
6
+ class Update < Operation::Update
7
+ class Contract < LedgerSync::Adaptors::Contract
8
+ schema do
9
+ required(:ledger_id).filled(:string)
10
+ required(:account).hash(Types::Reference)
11
+ required(:currency).filled(:string)
12
+ required(:memo).filled(:string)
13
+ required(:transaction_date).filled(:date?)
14
+ required(:exchange_rate).maybe(:float)
15
+ required(:line_items).array(Types::Reference)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def operate
22
+ ledger_resource_data = adaptor.find(
23
+ resource: 'deposit',
24
+ id: resource.ledger_id
25
+ )
26
+ response = adaptor.post(
27
+ resource: 'deposit',
28
+ payload: merge_into(from: local_resource_data, to: ledger_resource_data)
29
+ )
30
+
31
+ resource.ledger_id = response.dig('Id')
32
+ success(response: response)
33
+ end
34
+
35
+ def local_resource_data
36
+ {
37
+ 'CurrencyRef' => {
38
+ 'value' => resource.currency,
39
+ },
40
+ 'TxnDate' => resource.transaction_date.to_s, # Format: YYYY-MM-DD
41
+ 'PrivateNote' => resource.memo,
42
+ 'ExchangeRate' => resource.exchange_rate,
43
+ 'DepositToAccountRef' => {
44
+ 'value' => resource.account.ledger_id
45
+ },
46
+ 'Line' => resource.line_items.map do |line_item|
47
+ {
48
+ 'DetailType' => 'DepositLineDetail',
49
+ 'DepositLineDetail' => {
50
+ 'AccountRef' => {
51
+ 'value' => line_item.account&.ledger_id
52
+ }
53
+ },
54
+ 'Amount' => line_item.amount / 100.0,
55
+ 'Description' => line_item.description
56
+ }
57
+ end
58
+ }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../searcher'
3
+
4
+ module LedgerSync
5
+ module Adaptors
6
+ module QuickBooksOnline
7
+ module Deposit
8
+ class Searcher < QuickBooksOnline::Searcher
9
+ def resources
10
+ @resources ||= begin
11
+ adaptor
12
+ .query(
13
+ resource: 'deposit',
14
+ limit: limit,
15
+ offset: offset
16
+ )
17
+ .map do |c|
18
+ LedgerSync::Deposit.new(
19
+ ledger_id: c.fetch('Id')
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ module LedgerSync
2
+ module Adaptors
3
+ module QuickBooksOnline
4
+ module Expense
5
+ module Mapping
6
+ PAYMENT_TYPES = {
7
+ 'cash' => 'Cash',
8
+ 'check' => 'Check',
9
+ 'credit_card' => 'CreditCard',
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,68 @@
1
+ module LedgerSync
2
+ module Adaptors
3
+ module QuickBooksOnline
4
+ module Expense
5
+ module Operations
6
+ class Create < Operation::Create
7
+ class Contract < LedgerSync::Adaptors::Contract
8
+ params do
9
+ required(:ledger_id).value(:nil)
10
+ required(:vendor).hash(Types::Reference)
11
+ required(:account).hash(Types::Reference)
12
+ required(:amount).filled(:integer)
13
+ required(:currency).filled(:string)
14
+ required(:memo).filled(:string)
15
+ required(:payment_type).filled(:string)
16
+ required(:transaction_date).filled(:date?)
17
+ required(:exchange_rate).maybe(:float)
18
+ required(:line_items).array(Types::Reference)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def operate
25
+ response = adaptor.post(
26
+ resource: 'purchase',
27
+ payload: local_resource_data
28
+ )
29
+
30
+ resource.ledger_id = response.dig('Id')
31
+ success(response: response)
32
+ end
33
+
34
+ def local_resource_data
35
+ {
36
+ 'CurrencyRef' => {
37
+ 'value' => resource.currency,
38
+ },
39
+ 'PaymentType' => Mapping::PAYMENT_TYPES[resource.payment_type],
40
+ 'TxnDate' => resource.transaction_date.to_s, # Format: YYYY-MM-DD
41
+ 'PrivateNote' => resource.memo,
42
+ 'ExchangeRate' => resource.exchange_rate,
43
+ 'EntityRef' => {
44
+ 'value' => resource.vendor.ledger_id,
45
+ },
46
+ 'AccountRef' => {
47
+ 'value' => resource.account.ledger_id
48
+ },
49
+ 'Line' => resource.line_items.map do |line_item|
50
+ {
51
+ 'DetailType' => 'AccountBasedExpenseLineDetail',
52
+ 'AccountBasedExpenseLineDetail' => {
53
+ 'AccountRef' => {
54
+ 'value' => line_item.account&.ledger_id
55
+ }
56
+ },
57
+ 'Amount' => line_item.amount / 100.0,
58
+ 'Description' => line_item.description
59
+ }
60
+ end
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,39 @@
1
+ module LedgerSync
2
+ module Adaptors
3
+ module QuickBooksOnline
4
+ module Expense
5
+ module Operations
6
+ class Find < Operation::Find
7
+ class Contract < LedgerSync::Adaptors::Contract
8
+ schema do
9
+ required(:ledger_id).filled(:string)
10
+ required(:account).hash(Types::Reference)
11
+ required(:vendor).hash(Types::Reference)
12
+ required(:amount).maybe(:integer)
13
+ required(:currency).maybe(:string)
14
+ required(:memo).maybe(:string)
15
+ required(:payment_type).maybe(:string)
16
+ required(:transaction_date).filled(:date?)
17
+ required(:exchange_rate).maybe(:float)
18
+ required(:line_items).array(Types::Reference)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def operate
25
+ return failure(nil) if resource.ledger_id.nil?
26
+
27
+ response = adaptor.find(
28
+ resource: 'purchase',
29
+ id: resource.ledger_id
30
+ )
31
+
32
+ success(response: response)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end