forest_admin_datasource_mambu_payments 1.33.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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/Rakefile +6 -0
  4. data/forest_admin_datasource_mambu_payments.gemspec +37 -0
  5. data/lib/forest_admin_datasource_mambu_payments/client/reads.rb +66 -0
  6. data/lib/forest_admin_datasource_mambu_payments/client/writes.rb +42 -0
  7. data/lib/forest_admin_datasource_mambu_payments/client.rb +166 -0
  8. data/lib/forest_admin_datasource_mambu_payments/collections/account_holder.rb +64 -0
  9. data/lib/forest_admin_datasource_mambu_payments/collections/balance.rb +75 -0
  10. data/lib/forest_admin_datasource_mambu_payments/collections/base_collection.rb +254 -0
  11. data/lib/forest_admin_datasource_mambu_payments/collections/claim.rb +98 -0
  12. data/lib/forest_admin_datasource_mambu_payments/collections/connected_account.rb +103 -0
  13. data/lib/forest_admin_datasource_mambu_payments/collections/direct_debit_mandate.rb +125 -0
  14. data/lib/forest_admin_datasource_mambu_payments/collections/event.rb +133 -0
  15. data/lib/forest_admin_datasource_mambu_payments/collections/expected_payment.rb +132 -0
  16. data/lib/forest_admin_datasource_mambu_payments/collections/external_account.rb +121 -0
  17. data/lib/forest_admin_datasource_mambu_payments/collections/file.rb +89 -0
  18. data/lib/forest_admin_datasource_mambu_payments/collections/incoming_payment.rb +120 -0
  19. data/lib/forest_admin_datasource_mambu_payments/collections/internal_account.rb +136 -0
  20. data/lib/forest_admin_datasource_mambu_payments/collections/payee_verification_request.rb +88 -0
  21. data/lib/forest_admin_datasource_mambu_payments/collections/payment_capture.rb +136 -0
  22. data/lib/forest_admin_datasource_mambu_payments/collections/payment_order.rb +132 -0
  23. data/lib/forest_admin_datasource_mambu_payments/collections/reconciliation.rb +93 -0
  24. data/lib/forest_admin_datasource_mambu_payments/collections/return.rb +132 -0
  25. data/lib/forest_admin_datasource_mambu_payments/collections/transaction.rb +113 -0
  26. data/lib/forest_admin_datasource_mambu_payments/configuration.rb +36 -0
  27. data/lib/forest_admin_datasource_mambu_payments/datasource.rb +35 -0
  28. data/lib/forest_admin_datasource_mambu_payments/plugins/disable_search.rb +31 -0
  29. data/lib/forest_admin_datasource_mambu_payments/plugins/helpers.rb +94 -0
  30. data/lib/forest_admin_datasource_mambu_payments/plugins/messages.rb +30 -0
  31. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/holder_link_plugin.rb +56 -0
  32. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_account_holder_to_direct_debit_mandates.rb +14 -0
  33. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_account_holder_to_incoming_payments.rb +14 -0
  34. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_external_account_to_direct_debit_mandates.rb +13 -0
  35. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_external_account_to_incoming_payments.rb +13 -0
  36. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_external_account_to_payment_orders.rb +13 -0
  37. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_incoming_payment_to_events.rb +13 -0
  38. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_incoming_payment_to_expected_payments.rb +21 -0
  39. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_incoming_payment_to_returns.rb +12 -0
  40. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_incoming_payment_to_transactions.rb +20 -0
  41. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_internal_account_to_balances.rb +17 -0
  42. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_internal_account_to_incoming_payments.rb +13 -0
  43. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_internal_account_to_payment_orders.rb +17 -0
  44. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_payment_order_to_events.rb +13 -0
  45. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_payment_order_to_receiving_account_holder.rb +15 -0
  46. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_payment_order_to_returns.rb +12 -0
  47. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/link_payment_order_to_transactions.rb +51 -0
  48. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/one_to_many_link_plugin.rb +35 -0
  49. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/pivot_resolution.rb +73 -0
  50. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/two_step_connected_account_filter.rb +38 -0
  51. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/two_step_cross_reconciliation_filter.rb +55 -0
  52. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/two_step_holder_filter.rb +32 -0
  53. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/two_step_link_plugin.rb +64 -0
  54. data/lib/forest_admin_datasource_mambu_payments/plugins/relations/two_step_reconciliation_filter.rb +39 -0
  55. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/approve_payment_order.rb +56 -0
  56. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/cancel_payment_order.rb +66 -0
  57. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/create_account_holder.rb +44 -0
  58. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/create_external_account.rb +54 -0
  59. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/create_internal_account.rb +58 -0
  60. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/create_payment_order.rb +66 -0
  61. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/trigger_payee_verification.rb +58 -0
  62. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/update_account_holder.rb +67 -0
  63. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/update_external_account.rb +75 -0
  64. data/lib/forest_admin_datasource_mambu_payments/plugins/smart_actions/update_internal_account.rb +75 -0
  65. data/lib/forest_admin_datasource_mambu_payments/query/condition_tree_translator.rb +115 -0
  66. data/lib/forest_admin_datasource_mambu_payments/version.rb +3 -0
  67. data/lib/forest_admin_datasource_mambu_payments.rb +44 -0
  68. metadata +170 -0
@@ -0,0 +1,133 @@
1
+ module ForestAdminDatasourceMambuPayments
2
+ module Collections
3
+ class Event < BaseCollection
4
+ PolymorphicManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::PolymorphicManyToOneSchema
5
+
6
+ # Maps Numeral's `topic` / `related_object_type` enum values to Forest collection
7
+ # names. The polymorphic relation resolver expects the type column to hold the
8
+ # target collection name, so we translate at serialize time.
9
+ TYPE_TO_COLLECTION = {
10
+ 'payment_order' => 'MambuPaymentOrder',
11
+ 'transaction' => 'MambuTransaction',
12
+ 'incoming_payment' => 'MambuIncomingPayment',
13
+ 'expected_payment' => 'MambuExpectedPayment',
14
+ 'direct_debit_mandate' => 'MambuDirectDebitMandate',
15
+ 'balance' => 'MambuBalance',
16
+ 'connected_account' => 'MambuConnectedAccount',
17
+ 'account_holder' => 'MambuAccountHolder',
18
+ 'internal_account' => 'MambuInternalAccount',
19
+ 'external_account' => 'MambuExternalAccount'
20
+ }.freeze
21
+
22
+ ENUM_STATUS = %w[created delivered pending_retry failed archived].freeze
23
+
24
+ client_resource :event
25
+
26
+ def initialize(datasource)
27
+ super(datasource, 'MambuEvent')
28
+ define_schema
29
+ define_relations
30
+ reconcile_filter_operators!
31
+ end
32
+
33
+ def serialize(record)
34
+ a = attrs_of(record)
35
+ {
36
+ 'id' => a['id'],
37
+ 'object' => a['object'],
38
+ 'topic' => a['topic'],
39
+ 'type' => a['type'],
40
+ 'related_object_id' => a['related_object_id'],
41
+ 'related_object_type' => TYPE_TO_COLLECTION[a['related_object_type']] || a['related_object_type'],
42
+ 'status' => a['status'],
43
+ 'status_details' => a['status_details'],
44
+ 'webhook_id' => a['webhook_id'],
45
+ 'data' => a['data'],
46
+ 'created_at' => a['created_at']
47
+ }
48
+ end
49
+
50
+ protected
51
+
52
+ # Numeral's `GET /events` exposes filtering on the polymorphic target id.
53
+ # Used by OneToMany relations declared on PaymentOrder/IncomingPayment/etc
54
+ # to navigate "events of this resource". `related_object_type` filtering
55
+ # is left out because we translate the enum to Forest collection names at
56
+ # serialize time — uniqueness of UUIDs makes the type filter redundant
57
+ # when filtering by id anyway.
58
+ def collection_filters
59
+ {
60
+ 'related_object_id' => { ops: [Operators::EQUAL, Operators::IN] }
61
+ }
62
+ end
63
+
64
+ # PolymorphicManyToOne is not resolved by the customizer, so we populate
65
+ # `related_object` here when the projection requests it. Ids are grouped by
66
+ # their (translated) related_object_type so each target collection is hit
67
+ # with a single batched fetch_by_ids pass.
68
+ def embed_relations(rows, records, projection)
69
+ return if projection.nil? || !relations_in(projection).include?('related_object')
70
+
71
+ sources = records.map { |r| attrs_of(r) }
72
+ caches = build_related_object_caches(sources)
73
+
74
+ rows.each_with_index do |row, i|
75
+ src = sources[i]
76
+ type = TYPE_TO_COLLECTION[src['related_object_type']]
77
+ id = src['related_object_id']
78
+ next if type.nil? || id.to_s.empty?
79
+
80
+ row['related_object'] = caches.dig(type, id)
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def build_related_object_caches(sources)
87
+ ids_by_collection = Hash.new { |hash, key| hash[key] = [] }
88
+ sources.each do |src|
89
+ type = TYPE_TO_COLLECTION[src['related_object_type']]
90
+ id = src['related_object_id']
91
+ next if type.nil? || id.to_s.empty?
92
+
93
+ ids_by_collection[type] << id
94
+ end
95
+
96
+ ids_by_collection.to_h do |collection_name, ids|
97
+ target = datasource.get_collection(collection_name)
98
+ by_id = target.fetch_by_ids(ids).to_h do |raw|
99
+ [attrs_of(raw)['id'], target.serialize(raw)]
100
+ end
101
+ [collection_name, by_id]
102
+ end
103
+ end
104
+
105
+ def define_schema
106
+ add_field('id', ColumnSchema.new(column_type: 'String', is_primary_key: true,
107
+ is_read_only: true, is_sortable: true))
108
+ add_field('object', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
109
+ add_field('topic', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
110
+ add_field('type', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
111
+ add_field('related_object_id', ColumnSchema.new(column_type: 'String', is_read_only: true,
112
+ is_sortable: false))
113
+ add_field('related_object_type', ColumnSchema.new(column_type: 'String', is_read_only: true,
114
+ is_sortable: true))
115
+ add_field('status', ColumnSchema.new(column_type: 'Enum', enum_values: ENUM_STATUS,
116
+ is_read_only: true, is_sortable: true))
117
+ add_field('status_details', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
118
+ add_field('webhook_id', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
119
+ add_field('data', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
120
+ add_field('created_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
121
+ end
122
+
123
+ def define_relations
124
+ add_field('related_object', PolymorphicManyToOneSchema.new(
125
+ foreign_key: 'related_object_id',
126
+ foreign_key_type_field: 'related_object_type',
127
+ foreign_collections: TYPE_TO_COLLECTION.values,
128
+ foreign_key_targets: TYPE_TO_COLLECTION.values.to_h { |n| [n, 'id'] }
129
+ ))
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,132 @@
1
+ # rubocop:disable Metrics/ClassLength
2
+ module ForestAdminDatasourceMambuPayments
3
+ module Collections
4
+ class ExpectedPayment < BaseCollection
5
+ ManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema
6
+
7
+ ENUM_DIRECTION = %w[debit credit].freeze
8
+
9
+ client_resource :expected_payment
10
+
11
+ def initialize(datasource)
12
+ super(datasource, 'MambuExpectedPayment')
13
+ define_schema
14
+ define_relations
15
+ reconcile_filter_operators!
16
+ end
17
+
18
+ def create(_caller, data)
19
+ serialize(datasource.client.create_expected_payment(build_payload(data)))
20
+ end
21
+
22
+ def update(caller, filter, patch)
23
+ payload = build_payload(patch)
24
+ ids_for(caller, filter).each { |id| datasource.client.update_expected_payment(id, payload) }
25
+ end
26
+
27
+ def delete(caller, filter)
28
+ ids_for(caller, filter).each { |id| datasource.client.delete_expected_payment(id) }
29
+ end
30
+
31
+ def serialize(record)
32
+ a = attrs_of(record)
33
+ {
34
+ 'id' => a['id'],
35
+ 'object' => a['object'],
36
+ 'idempotency_key' => a['idempotency_key'],
37
+ 'connected_account_id' => a['connected_account_id'],
38
+ 'internal_account_id' => a['internal_account_id'],
39
+ 'external_account_id' => a['external_account_id'],
40
+ 'direction' => a['direction'],
41
+ 'amount_from' => a['amount_from'],
42
+ 'amount_to' => a['amount_to'],
43
+ 'currency' => a['currency'],
44
+ 'start_date' => a['start_date'],
45
+ 'end_date' => a['end_date'],
46
+ 'descriptions' => a['descriptions'],
47
+ 'reconciliation_status' => a['reconciliation_status'],
48
+ 'reconciled_amount' => a['reconciled_amount'],
49
+ 'custom_fields' => a['custom_fields'],
50
+ 'metadata' => a['metadata'],
51
+ 'created_at' => a['created_at'],
52
+ 'updated_at' => a['updated_at'],
53
+ 'canceled_at' => a['canceled_at']
54
+ }
55
+ end
56
+
57
+ protected
58
+
59
+ def collection_filters
60
+ {
61
+ 'connected_account_id' => { ops: [Operators::EQUAL, Operators::IN] },
62
+ 'internal_account_id' => { ops: [Operators::EQUAL, Operators::IN] },
63
+ 'external_account_id' => { ops: [Operators::EQUAL, Operators::IN] }
64
+ }
65
+ end
66
+
67
+ # The full account records are exposed through the ManyToOne relations
68
+ # below rather than as embedded snapshot columns, so a single source of
69
+ # truth backs both (mirrors the Transaction collection).
70
+ def many_to_one_embeds
71
+ [
72
+ { foreign_key: 'connected_account_id', relation_name: 'connected_account',
73
+ collection: 'MambuConnectedAccount' },
74
+ { foreign_key: 'internal_account_id', relation_name: 'internal_account',
75
+ collection: 'MambuInternalAccount' },
76
+ { foreign_key: 'external_account_id', relation_name: 'external_account',
77
+ collection: 'MambuExternalAccount' }
78
+ ]
79
+ end
80
+
81
+ private
82
+
83
+ def define_schema
84
+ add_field('id', ColumnSchema.new(column_type: 'String', is_primary_key: true,
85
+ is_read_only: true, is_sortable: true))
86
+ add_field('object', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
87
+ add_field('idempotency_key', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
88
+ add_field('connected_account_id', ColumnSchema.new(column_type: 'String',
89
+ is_read_only: false, is_sortable: true))
90
+ add_field('internal_account_id', ColumnSchema.new(column_type: 'String',
91
+ is_read_only: false, is_sortable: false))
92
+ add_field('external_account_id', ColumnSchema.new(column_type: 'String',
93
+ is_read_only: false, is_sortable: false))
94
+ add_field('direction', ColumnSchema.new(column_type: 'Enum', enum_values: ENUM_DIRECTION,
95
+ is_read_only: false, is_sortable: true))
96
+ add_field('amount_from', ColumnSchema.new(column_type: 'Number', is_read_only: false, is_sortable: false))
97
+ add_field('amount_to', ColumnSchema.new(column_type: 'Number', is_read_only: false, is_sortable: false))
98
+ add_field('currency', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
99
+ add_field('start_date', ColumnSchema.new(column_type: 'Date', is_read_only: false, is_sortable: true))
100
+ add_field('end_date', ColumnSchema.new(column_type: 'Date', is_read_only: false, is_sortable: true))
101
+ add_field('descriptions', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
102
+ add_field('reconciliation_status', ColumnSchema.new(column_type: 'String', is_read_only: true,
103
+ is_sortable: true))
104
+ add_field('reconciled_amount', ColumnSchema.new(column_type: 'Number', is_read_only: true, is_sortable: false))
105
+ add_field('custom_fields', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
106
+ add_field('metadata', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
107
+ add_field('created_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
108
+ add_field('updated_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
109
+ add_field('canceled_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
110
+ end
111
+
112
+ def define_relations
113
+ add_field('connected_account', ManyToOneSchema.new(
114
+ foreign_collection: 'MambuConnectedAccount',
115
+ foreign_key: 'connected_account_id',
116
+ foreign_key_target: 'id'
117
+ ))
118
+ add_field('internal_account', ManyToOneSchema.new(
119
+ foreign_collection: 'MambuInternalAccount',
120
+ foreign_key: 'internal_account_id',
121
+ foreign_key_target: 'id'
122
+ ))
123
+ add_field('external_account', ManyToOneSchema.new(
124
+ foreign_collection: 'MambuExternalAccount',
125
+ foreign_key: 'external_account_id',
126
+ foreign_key_target: 'id'
127
+ ))
128
+ end
129
+ end
130
+ end
131
+ end
132
+ # rubocop:enable Metrics/ClassLength
@@ -0,0 +1,121 @@
1
+ # rubocop:disable Metrics/ClassLength, Metrics/MethodLength
2
+ module ForestAdminDatasourceMambuPayments
3
+ module Collections
4
+ class ExternalAccount < BaseCollection
5
+ ManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema
6
+
7
+ client_resource :external_account
8
+
9
+ def initialize(datasource)
10
+ super(datasource, 'MambuExternalAccount')
11
+ define_schema
12
+ define_relations
13
+ reconcile_filter_operators!
14
+ end
15
+
16
+ def create(_caller, data)
17
+ serialize(datasource.client.create_external_account(build_payload(data)))
18
+ end
19
+
20
+ def update(caller, filter, patch)
21
+ payload = build_payload(patch)
22
+ ids_for(caller, filter).each { |id| datasource.client.update_external_account(id, payload) }
23
+ end
24
+
25
+ def delete(caller, filter)
26
+ ids_for(caller, filter).each { |id| datasource.client.delete_external_account(id) }
27
+ end
28
+
29
+ def serialize(record)
30
+ a = attrs_of(record)
31
+ {
32
+ 'id' => a['id'],
33
+ 'object' => a['object'],
34
+ 'type' => a['type'],
35
+ 'status' => a['status'],
36
+ 'status_details' => a['status_details'],
37
+ 'name' => a['name'],
38
+ 'holder_name' => a['holder_name'],
39
+ 'holder_address' => a['holder_address'],
40
+ 'account_number' => a['account_number'],
41
+ 'account_number_format' => a['account_number_format'],
42
+ 'bank_code' => a['bank_code'],
43
+ 'bank_name' => a['bank_name'],
44
+ 'bank_address' => a['bank_address'],
45
+ 'bank_code_format' => a['bank_code_format'],
46
+ 'account_holder_id' => a['account_holder_id'],
47
+ 'organization_identification' => a['organization_identification'],
48
+ 'company_registration_number' => a['company_registration_number'],
49
+ 'company_registration_number_type' => a['company_registration_number_type'],
50
+ 'metadata' => a['metadata'],
51
+ 'custom_fields' => a['custom_fields'],
52
+ 'account_verification' => a['account_verification'],
53
+ 'idempotency_key' => a['idempotency_key'],
54
+ 'created_at' => a['created_at'],
55
+ 'disabled_at' => a['disabled_at']
56
+ }
57
+ end
58
+
59
+ protected
60
+
61
+ def collection_filters
62
+ {
63
+ 'account_holder_id' => { ops: [Operators::EQUAL, Operators::IN] }
64
+ }
65
+ end
66
+
67
+ def many_to_one_embeds
68
+ [
69
+ { foreign_key: 'account_holder_id', relation_name: 'account_holder',
70
+ collection: 'MambuAccountHolder' }
71
+ ]
72
+ end
73
+
74
+ private
75
+
76
+ def define_schema
77
+ add_field('id', ColumnSchema.new(column_type: 'String', is_primary_key: true,
78
+ is_read_only: true, is_sortable: true))
79
+ add_field('object', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
80
+ add_field('type', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: true))
81
+ add_field('status', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
82
+ add_field('status_details', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
83
+ add_field('name', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: true))
84
+ add_field('holder_name', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
85
+ add_field('holder_address', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
86
+ add_field('account_number', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
87
+ add_field('account_number_format', ColumnSchema.new(column_type: 'String', is_read_only: false,
88
+ is_sortable: false))
89
+ add_field('bank_code', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
90
+ add_field('bank_name', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
91
+ add_field('bank_address', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
92
+ add_field('bank_code_format', ColumnSchema.new(column_type: 'String', is_read_only: false,
93
+ is_sortable: false))
94
+ add_field('account_holder_id', ColumnSchema.new(column_type: 'String', is_read_only: false,
95
+ is_sortable: true))
96
+ add_field('organization_identification', ColumnSchema.new(column_type: 'Json', is_read_only: false,
97
+ is_sortable: false))
98
+ add_field('company_registration_number', ColumnSchema.new(column_type: 'String', is_read_only: false,
99
+ is_sortable: false))
100
+ add_field('company_registration_number_type',
101
+ ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
102
+ add_field('metadata', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
103
+ add_field('custom_fields', ColumnSchema.new(column_type: 'Json', is_read_only: false, is_sortable: false))
104
+ add_field('account_verification', ColumnSchema.new(column_type: 'Json', is_read_only: true,
105
+ is_sortable: false))
106
+ add_field('idempotency_key', ColumnSchema.new(column_type: 'String', is_read_only: false, is_sortable: false))
107
+ add_field('created_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
108
+ add_field('disabled_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
109
+ end
110
+
111
+ def define_relations
112
+ add_field('account_holder', ManyToOneSchema.new(
113
+ foreign_collection: 'MambuAccountHolder',
114
+ foreign_key: 'account_holder_id',
115
+ foreign_key_target: 'id'
116
+ ))
117
+ end
118
+ end
119
+ end
120
+ end
121
+ # rubocop:enable Metrics/ClassLength, Metrics/MethodLength
@@ -0,0 +1,89 @@
1
+ module ForestAdminDatasourceMambuPayments
2
+ module Collections
3
+ class File < BaseCollection
4
+ ManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema
5
+
6
+ ENUM_DIRECTION = %w[incoming outgoing].freeze
7
+ ENUM_STATUS = %w[created approved canceled sent rejected processed received].freeze
8
+
9
+ client_resource :file
10
+
11
+ def initialize(datasource)
12
+ super(datasource, 'MambuFile')
13
+ define_schema
14
+ define_relations
15
+ reconcile_filter_operators!
16
+ end
17
+
18
+ def serialize(record)
19
+ a = attrs_of(record)
20
+ {
21
+ 'id' => a['id'],
22
+ 'object' => a['object'],
23
+ 'connected_account_id' => a['connected_account_id'],
24
+ 'connected_account_ids' => a['connected_account_ids'],
25
+ 'direction' => a['direction'],
26
+ 'category' => a['category'],
27
+ 'format' => a['format'],
28
+ 'filename' => a['filename'],
29
+ 'size' => a['size'],
30
+ 'summary' => a['summary'],
31
+ 'status' => a['status'],
32
+ 'status_details' => a['status_details'],
33
+ 'bank_data' => a['bank_data'],
34
+ 'created_at' => a['created_at']
35
+ }
36
+ end
37
+
38
+ protected
39
+
40
+ def collection_filters
41
+ {
42
+ 'connected_account_id' => { ops: [Operators::EQUAL, Operators::IN] }
43
+ }
44
+ end
45
+
46
+ def many_to_one_embeds
47
+ [
48
+ { foreign_key: 'connected_account_id', relation_name: 'connected_account',
49
+ collection: 'MambuConnectedAccount' }
50
+ ]
51
+ end
52
+
53
+ private
54
+
55
+ def define_schema
56
+ add_field('id', ColumnSchema.new(column_type: 'String', is_primary_key: true,
57
+ is_read_only: true, is_sortable: true))
58
+ add_field('object', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
59
+ add_field('connected_account_id', ColumnSchema.new(column_type: 'String',
60
+ is_read_only: true, is_sortable: true))
61
+ # The API also returns connected_account_ids (an array) for files that
62
+ # aggregate operations across multiple accounts; surfaced as Json since
63
+ # Forest can't model an array of foreign keys natively.
64
+ add_field('connected_account_ids', ColumnSchema.new(column_type: 'Json', is_read_only: true,
65
+ is_sortable: false))
66
+ add_field('direction', ColumnSchema.new(column_type: 'Enum', enum_values: ENUM_DIRECTION,
67
+ is_read_only: true, is_sortable: true))
68
+ add_field('category', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
69
+ add_field('format', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
70
+ add_field('filename', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
71
+ add_field('size', ColumnSchema.new(column_type: 'Number', is_read_only: true, is_sortable: true))
72
+ add_field('summary', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
73
+ add_field('status', ColumnSchema.new(column_type: 'Enum', enum_values: ENUM_STATUS,
74
+ is_read_only: true, is_sortable: true))
75
+ add_field('status_details', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
76
+ add_field('bank_data', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
77
+ add_field('created_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
78
+ end
79
+
80
+ def define_relations
81
+ add_field('connected_account', ManyToOneSchema.new(
82
+ foreign_collection: 'MambuConnectedAccount',
83
+ foreign_key: 'connected_account_id',
84
+ foreign_key_target: 'id'
85
+ ))
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,120 @@
1
+ # rubocop:disable Metrics/ClassLength, Metrics/MethodLength
2
+ module ForestAdminDatasourceMambuPayments
3
+ module Collections
4
+ class IncomingPayment < BaseCollection
5
+ ManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema
6
+
7
+ client_resource :incoming_payment
8
+
9
+ def initialize(datasource)
10
+ super(datasource, 'MambuIncomingPayment')
11
+ define_schema
12
+ define_relations
13
+ reconcile_filter_operators!
14
+ end
15
+
16
+ def serialize(record)
17
+ a = attrs_of(record)
18
+ {
19
+ 'id' => a['id'],
20
+ 'object' => a['object'],
21
+ 'connected_account_id' => a['connected_account_id'],
22
+ 'type' => a['type'],
23
+ 'status' => a['status'],
24
+ 'amount' => a['amount'],
25
+ 'currency' => a['currency'],
26
+ 'end_to_end_id' => a['end_to_end_id'],
27
+ 'uetr' => a['uetr'],
28
+ 'reference' => a['reference'],
29
+ 'structured_reference' => a['structured_reference'],
30
+ 'value_date' => a['value_date'],
31
+ 'booking_date' => a['booking_date'],
32
+ 'originating_account' => a['originating_account'],
33
+ 'receiving_account' => a['receiving_account'],
34
+ 'internal_account_id' => a['internal_account_id'],
35
+ 'external_account_id' => a['external_account_id'],
36
+ 'reconciliation_status' => a['reconciliation_status'],
37
+ 'reconciled_amount' => a['reconciled_amount'],
38
+ 'return_information' => a['return_information'],
39
+ 'custom_fields' => a['custom_fields'],
40
+ 'metadata' => a['metadata'],
41
+ 'created_at' => a['created_at']
42
+ }
43
+ end
44
+
45
+ protected
46
+
47
+ def collection_filters
48
+ {
49
+ 'connected_account_id' => { ops: [Operators::EQUAL, Operators::IN] },
50
+ 'internal_account_id' => { ops: [Operators::EQUAL, Operators::IN] },
51
+ 'external_account_id' => { ops: [Operators::EQUAL, Operators::IN] }
52
+ }
53
+ end
54
+
55
+ def many_to_one_embeds
56
+ [
57
+ { foreign_key: 'connected_account_id', relation_name: 'connected_account',
58
+ collection: 'MambuConnectedAccount' },
59
+ { foreign_key: 'internal_account_id', relation_name: 'internal_account',
60
+ collection: 'MambuInternalAccount' },
61
+ { foreign_key: 'external_account_id', relation_name: 'external_account',
62
+ collection: 'MambuExternalAccount' }
63
+ ]
64
+ end
65
+
66
+ private
67
+
68
+ def define_schema
69
+ add_field('id', ColumnSchema.new(column_type: 'String', is_primary_key: true,
70
+ is_read_only: true, is_sortable: true))
71
+ add_field('object', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
72
+ add_field('connected_account_id', ColumnSchema.new(column_type: 'String',
73
+ is_read_only: true, is_sortable: true))
74
+ add_field('type', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
75
+ add_field('status', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: true))
76
+ add_field('amount', ColumnSchema.new(column_type: 'Number', is_read_only: true, is_sortable: false))
77
+ add_field('currency', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
78
+ add_field('end_to_end_id', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
79
+ add_field('uetr', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
80
+ add_field('reference', ColumnSchema.new(column_type: 'String', is_read_only: true, is_sortable: false))
81
+ add_field('structured_reference', ColumnSchema.new(column_type: 'String',
82
+ is_read_only: true, is_sortable: false))
83
+ add_field('value_date', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
84
+ add_field('booking_date', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
85
+ add_field('originating_account', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
86
+ add_field('receiving_account', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
87
+ add_field('internal_account_id', ColumnSchema.new(column_type: 'String',
88
+ is_read_only: true, is_sortable: false))
89
+ add_field('external_account_id', ColumnSchema.new(column_type: 'String',
90
+ is_read_only: true, is_sortable: false))
91
+ add_field('reconciliation_status', ColumnSchema.new(column_type: 'String',
92
+ is_read_only: true, is_sortable: true))
93
+ add_field('reconciled_amount', ColumnSchema.new(column_type: 'Number', is_read_only: true, is_sortable: false))
94
+ add_field('return_information', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
95
+ add_field('custom_fields', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
96
+ add_field('metadata', ColumnSchema.new(column_type: 'Json', is_read_only: true, is_sortable: false))
97
+ add_field('created_at', ColumnSchema.new(column_type: 'Date', is_read_only: true, is_sortable: true))
98
+ end
99
+
100
+ def define_relations
101
+ add_field('connected_account', ManyToOneSchema.new(
102
+ foreign_collection: 'MambuConnectedAccount',
103
+ foreign_key: 'connected_account_id',
104
+ foreign_key_target: 'id'
105
+ ))
106
+ add_field('internal_account', ManyToOneSchema.new(
107
+ foreign_collection: 'MambuInternalAccount',
108
+ foreign_key: 'internal_account_id',
109
+ foreign_key_target: 'id'
110
+ ))
111
+ add_field('external_account', ManyToOneSchema.new(
112
+ foreign_collection: 'MambuExternalAccount',
113
+ foreign_key: 'external_account_id',
114
+ foreign_key_target: 'id'
115
+ ))
116
+ end
117
+ end
118
+ end
119
+ end
120
+ # rubocop:enable Metrics/ClassLength, Metrics/MethodLength