faithteams-api 2.0.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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +11 -0
  3. data/.github/CODEOWNERS +1 -0
  4. data/.github/CONTRIBUTING.md +35 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +8 -0
  6. data/.github/workflows/jeweler.yml +11 -0
  7. data/.github/workflows/puller.yml +17 -0
  8. data/.gitignore +16 -0
  9. data/.rspec +2 -0
  10. data/.rubocop.yml +227 -0
  11. data/.tool-versions +1 -0
  12. data/CHANGELOG.md +70 -0
  13. data/CODE_OF_CONDUCT.md +128 -0
  14. data/Gemfile +6 -0
  15. data/Gemfile.lock +171 -0
  16. data/Guardfile +50 -0
  17. data/LICENSE +21 -0
  18. data/README.md +85 -0
  19. data/Rakefile +8 -0
  20. data/bin/console +15 -0
  21. data/bin/setup +8 -0
  22. data/faithteams-api.gemspec +47 -0
  23. data/guides/api_client_interface.md +18 -0
  24. data/guides/release-process.md +11 -0
  25. data/lib/faithteams/api/v2/connection.rb +142 -0
  26. data/lib/faithteams/api/v2/entity/base.rb +36 -0
  27. data/lib/faithteams/api/v2/entity/batch.rb +68 -0
  28. data/lib/faithteams/api/v2/entity/contribution.rb +19 -0
  29. data/lib/faithteams/api/v2/entity/contribution_record.rb +137 -0
  30. data/lib/faithteams/api/v2/entity/contribution_type.rb +37 -0
  31. data/lib/faithteams/api/v2/entity/fund.rb +52 -0
  32. data/lib/faithteams/api/v2/entity/person.rb +77 -0
  33. data/lib/faithteams/api/v2/entity.rb +17 -0
  34. data/lib/faithteams/api/v2/error/no_search_parameter_provided.rb +12 -0
  35. data/lib/faithteams/api/v2/error/request.rb +46 -0
  36. data/lib/faithteams/api/v2/error.rb +13 -0
  37. data/lib/faithteams/api/v2/gateway.rb +51 -0
  38. data/lib/faithteams/api/v2/gateway_base.rb +25 -0
  39. data/lib/faithteams/api/v2/resource/base.rb +46 -0
  40. data/lib/faithteams/api/v2/resource/batch.rb +58 -0
  41. data/lib/faithteams/api/v2/resource/contribution.rb +39 -0
  42. data/lib/faithteams/api/v2/resource/contribution_type.rb +38 -0
  43. data/lib/faithteams/api/v2/resource/fund.rb +22 -0
  44. data/lib/faithteams/api/v2/resource/person.rb +48 -0
  45. data/lib/faithteams/api/v2/resource/user.rb +40 -0
  46. data/lib/faithteams/api/v2/resource.rb +18 -0
  47. data/lib/faithteams/api/v2.rb +15 -0
  48. data/lib/faithteams/api.rb +8 -0
  49. data/lib/faithteams/version.rb +6 -0
  50. data/lib/faithteams.rb +7 -0
  51. data/thunder-tests/.gitignore +2 -0
  52. data/thunder-tests/collections/tc_col_faithteams.json +2390 -0
  53. data/thunder-tests/environments/tc_env_faithteams.json +59 -0
  54. data/thunder-tests/faithteams.env.template +5 -0
  55. metadata +283 -0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Entity
7
+ # Wraps a faithteams contribution object.
8
+ class Contribution < Base
9
+ # @return [Array<ContributionRecord>] the contribution records
10
+ def records
11
+ attributes.map do |record|
12
+ FaithTeams::API::V2::Entity::ContributionRecord.new(attributes: record)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Entity
7
+ # Wraps a faithteams contribution_record object.
8
+ class ContributionRecord < Base
9
+ # @return [Float, nil]
10
+ def amount
11
+ read_attribute(:amount)
12
+ end
13
+
14
+ # @return [Integer, nil]
15
+ def batch_id
16
+ read_attribute(:batchId)
17
+ end
18
+
19
+ # @return [String, nil]
20
+ def check_number
21
+ read_attribute(:checkNumber).presence
22
+ end
23
+
24
+ # @return [Integer, nil]
25
+ def contribution_id
26
+ read_attribute(:contributionId)
27
+ end
28
+
29
+ # @return [Integer, nil]
30
+ def contribution_type_id
31
+ read_attribute(:contributionTypeId)
32
+ end
33
+
34
+ # @return [String, nil]
35
+ def contribution_type_name
36
+ read_attribute(:contributionTypeName).presence
37
+ end
38
+
39
+ # @return [String, nil]
40
+ def created_datetime
41
+ read_attribute(:createdDtm).presence
42
+ end
43
+
44
+ # @return [Integer, nil]
45
+ def created_user_id
46
+ read_attribute(:createdUser)
47
+ end
48
+
49
+ # @return [Float, nil]
50
+ def fee
51
+ read_attribute(:fee)
52
+ end
53
+
54
+ # @return [Integer, nil]
55
+ def fund_id
56
+ read_attribute(:fundId)
57
+ end
58
+
59
+ # @return [String, nil]
60
+ def fund_name
61
+ read_attribute(:fundName).presence
62
+ end
63
+
64
+ # @return [String, nil]
65
+ def give_datetime
66
+ read_attribute(:giveDtm).presence
67
+ end
68
+
69
+ # @return [Float, nil]
70
+ def net_amount
71
+ read_attribute(:netAmount)
72
+ end
73
+
74
+ # @return [String, nil]
75
+ def note
76
+ read_attribute(:note).presence
77
+ end
78
+
79
+ # @return [Integer, nil]
80
+ def org_id
81
+ read_attribute(:orgId)
82
+ end
83
+
84
+ # @return [Integer, nil]
85
+ def parent_id
86
+ read_attribute(:parentId)
87
+ end
88
+
89
+ # @return [Integer, nil]
90
+ def person_id
91
+ read_attribute(:personId)
92
+ end
93
+
94
+ # @return [Integer, nil]
95
+ def person_id_2
96
+ read_attribute(:personId2)
97
+ end
98
+
99
+ # @return [String, nil] "H" for header, "D" for detail
100
+ def record_type
101
+ read_attribute(:recordType).presence
102
+ end
103
+
104
+ # @return [String, nil] "A" for active?
105
+ def status
106
+ read_attribute(:status).presence
107
+ end
108
+
109
+ # @return [Float, nil]
110
+ def total_amount
111
+ read_attribute(:totalAmount)
112
+ end
113
+
114
+ # @return [String, nil]
115
+ def updated_datetime
116
+ read_attribute(:updatedDtm).presence
117
+ end
118
+
119
+ # @return [Integer, nil]
120
+ def updated_user_id
121
+ read_attribute(:updatedUser)
122
+ end
123
+
124
+ # @return [Boolean]
125
+ def header?
126
+ record_type&.upcase == "H"
127
+ end
128
+
129
+ # @return [Boolean]
130
+ def detail?
131
+ record_type&.upcase == "D"
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Entity
7
+ # Wraps a faithteams contribution type object.
8
+ class ContributionType < Base
9
+ # @return [Integer, nil]
10
+ def id
11
+ read_attribute(:contributionTypeId)
12
+ end
13
+
14
+ # @return [String, nil]
15
+ def name
16
+ read_attribute(:name).presence
17
+ end
18
+
19
+ # @return [String, nil] "A" for active, "I" for inactive
20
+ def status
21
+ read_attribute(:status).presence
22
+ end
23
+
24
+ # @return [Boolean]
25
+ def tithely?
26
+ (name || "").strip.downcase == "tithely"
27
+ end
28
+
29
+ # @return [Boolean]
30
+ def active?
31
+ (status || "I").strip.upcase == "A"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Entity
7
+ # Wraps a faithteams fund object.
8
+ class Fund < Base
9
+ # @return [String, nil] "N" for no, "Y" for yes
10
+ def default
11
+ read_attribute(:isDefault).presence
12
+ end
13
+
14
+ # @return [String, nil]
15
+ def description
16
+ read_attribute(:description).presence
17
+ end
18
+
19
+ # @return [Integer, nil]
20
+ def fund_id
21
+ read_attribute(:fundId)
22
+ end
23
+
24
+ # @return [String, nil]
25
+ def name
26
+ read_attribute(:name).presence
27
+ end
28
+
29
+ # @return [String, nil] "A" for active, "I" for inactive
30
+ def online_status
31
+ read_attribute(:onlineStatus).presence
32
+ end
33
+
34
+ # @return [Integer, nil]
35
+ def org_id
36
+ read_attribute(:orgId)
37
+ end
38
+
39
+ # @return [String, nil] "A" for active, "I" for inactive
40
+ def status
41
+ read_attribute(:status).presence
42
+ end
43
+
44
+ # @return [String, nil] "T" for true?, "Y" for yes?
45
+ def tax_deductible
46
+ read_attribute(:taxDeductible).presence
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Entity
7
+ # Wraps an faithteams person object
8
+ class Person < Base
9
+ # @return [String, nil]
10
+ def email
11
+ read_attribute(:homeEmail).presence
12
+ end
13
+
14
+ # @return [String, nil]
15
+ def first_name
16
+ read_attribute(:firstName).presence
17
+ end
18
+
19
+ # @return [String, nil]
20
+ def home_address_city
21
+ read_attribute(:homeAddressCity).presence
22
+ end
23
+
24
+ # @return [String, nil]
25
+ def home_address_country
26
+ read_attribute(:homeAddressCountry).presence
27
+ end
28
+
29
+ # @return [String, nil]
30
+ def home_address_state
31
+ read_attribute(:homeAddressState).presence
32
+ end
33
+
34
+ # @return [String, nil]
35
+ def home_address_street_line1
36
+ read_attribute(:homeAddressStreetLine1).presence
37
+ end
38
+
39
+ # @return [String, nil]
40
+ def home_address_street_line2
41
+ read_attribute(:homeAddressStreetLine2).presence
42
+ end
43
+
44
+ # @return [String, nil]
45
+ def home_address_zip
46
+ read_attribute(:homeAddressZip).presence
47
+ end
48
+
49
+ # @return [String, nil]
50
+ def home_phone_number
51
+ read_attribute(:homePhoneNumber).presence
52
+ end
53
+
54
+ # @return [Integer, nil]
55
+ def id
56
+ read_attribute(:personId)
57
+ end
58
+
59
+ # @return [String, nil]
60
+ def last_name
61
+ read_attribute(:lastName).presence
62
+ end
63
+
64
+ # @return [Integer, nil]
65
+ def org_id
66
+ read_attribute(:orgId)
67
+ end
68
+
69
+ # @return [String, nil] "A" for active, "I" for inactive
70
+ def status
71
+ read_attribute(:status).presence
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "entity/base"
4
+ require_relative "entity/batch"
5
+ require_relative "entity/contribution"
6
+ require_relative "entity/contribution_record"
7
+ require_relative "entity/contribution_type"
8
+ require_relative "entity/fund"
9
+ require_relative "entity/person"
10
+
11
+ module FaithTeams
12
+ module API
13
+ module V2
14
+ module Entity; end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Error
7
+ # Thrown when a parameter is not given but should have been
8
+ class NoSearchParameterProvided < StandardError; end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Error
7
+ # A request failed to complete successfully.
8
+ class Request < StandardError
9
+ attr_reader :response
10
+
11
+ # Custom faithteams error about invalid API key
12
+ UNAUTHORIZED_ERROR_MESSAGE = "Unauthorized"
13
+
14
+ # Custom faithteams error when a resource is not found
15
+ NOT_FOUND_ERROR_MESSAGE = "Not Found"
16
+
17
+ # @param response [HTTP::Response]
18
+ # @param message [String]
19
+ def initialize(response:, message: "Request failed", skip_failure_message: false)
20
+ @response = response
21
+ message += ": #{failure_message}" unless failure_message.blank? || skip_failure_message
22
+ super(message)
23
+ end
24
+
25
+ # @return [String]
26
+ def failure_message
27
+ @failure_message ||= response.parse(:json).dig("message") rescue ""
28
+ rescue JSON::ParserError => e
29
+ e.capture
30
+ response.to_s
31
+ end
32
+
33
+ # @return [Boolean]
34
+ def unauthorized?
35
+ failure_message == UNAUTHORIZED_ERROR_MESSAGE
36
+ end
37
+
38
+ # @return [Boolean]
39
+ def not_found?
40
+ failure_message == NOT_FOUND_ERROR_MESSAGE
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "error/no_search_parameter_provided"
4
+ require_relative "error/request"
5
+
6
+ module FaithTeams
7
+ module API
8
+ module V2
9
+ # FaithTeams API error
10
+ module Error; end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gateway_base"
4
+
5
+ module FaithTeams
6
+ module API
7
+ module V2
8
+ # Central gateway for all API resources
9
+ class Gateway < GatewayBase
10
+ # @param connection [FaithTeams::API::V2::Connection]
11
+ def initialize(connection:)
12
+ @connection = connection
13
+ end
14
+
15
+ # @return [Resource::Batch]
16
+ def batch
17
+ @batch ||= Resource::Batch.new(connection: connection)
18
+ end
19
+
20
+ # @return [Resource::Fund]
21
+ def fund
22
+ @fund ||= Resource::Fund.new(connection: connection)
23
+ end
24
+
25
+ # @return [Resource::Person]
26
+ def person
27
+ @person ||= Resource::Person.new(connection: connection)
28
+ end
29
+
30
+ # @return [Resource::Contribution]
31
+ def contribution
32
+ @contribution ||= Resource::Contribution.new(connection: connection)
33
+ end
34
+
35
+ # @return [Resource::User]
36
+ def user
37
+ @user ||= Resource::User.new(connection: connection)
38
+ end
39
+
40
+ # @return [Resource::ContributionType]
41
+ def contribution_type
42
+ @contribution_type ||= Resource::ContributionType.new(connection: connection)
43
+ end
44
+
45
+ def valid_connection?
46
+ connection.valid?
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ # A base class for all FaithTeam API versions
7
+ class GatewayBase
8
+ # @param connection [Integrations::API::Connection]
9
+ def initialize(connection:)
10
+ @connection = connection
11
+ end
12
+
13
+ # Required by integrations-gem
14
+ # @return [Boolean]
15
+ def valid_connection?
16
+ connection.valid?
17
+ end
18
+
19
+ protected
20
+
21
+ attr_reader :connection
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+ require "active_support/core_ext/object/blank"
5
+
6
+ module FaithTeams
7
+ module API
8
+ module V2
9
+ module Resource
10
+ # Common Resource functionality
11
+ # Additional methods can be added but the following methods should not be missing
12
+ class Base < GatewayBase
13
+ # @param id [Integer] The contribution payment_id.
14
+ # @return [Entity::Base, nil]
15
+ def find(id:)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ # @param args [Hash] Key values to search with
20
+ # @return [Array<Entity::Base>]
21
+ def search(**args)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ # @param entity [Entity::Base]
26
+ # @return [Entity::Base, false]
27
+ def create(entity:)
28
+ raise NotImplementedError
29
+ end
30
+
31
+ # @param entity [Entity::Base]
32
+ # @return [Entity::Base, false]
33
+ def update(entity:)
34
+ raise NotImplementedError
35
+ end
36
+
37
+ # @param id [#to_s] ID of the entity to delete
38
+ # @return [Boolean]
39
+ def delete(id:)
40
+ raise NotImplementedError
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Resource
7
+ # Batch resource
8
+ class Batch < Base
9
+ # @param args [Hash] Keyword args
10
+ # @return [Array<Entity::Batch>]
11
+ def search(**args)
12
+ found = connection.get(path: "/batches", params: args)["data"]
13
+ return [] unless found.present?
14
+
15
+ found.map { |b| Entity::Batch.new(attributes: b) }
16
+ end
17
+
18
+ # @param id [Integer]
19
+ # @return [Entity::Batch, nil] containing all batch details
20
+ # @raise [Error::Request]
21
+ def find(id:)
22
+ raise FaithTeams::API::V2::Error::NoSearchParameterProvided if id.nil?
23
+
24
+ data = connection.get(path: "/batches/#{id}")["data"]
25
+ return nil unless data
26
+
27
+ Entity::Batch.new(attributes: data)
28
+ rescue Error::Request => e
29
+ return nil if e.response.code == 404
30
+ raise
31
+ end
32
+
33
+ # Searches for a batch by `dtm` and `title`
34
+ # @note The batches endpoint does not actually filter by title so we do the filtering here.
35
+ # @param batch [Entity::Batch]
36
+ # @return [Entity::Batch, nil]
37
+ def find_by_batch(batch:)
38
+ found = search(sort: "dtm", sortDirection: "desc", dtm: batch.created_datetime)
39
+ found.find { |b| !b.deleted? && b.title == batch.title }
40
+ end
41
+
42
+ # The response sends back the created batch in the `data` object.
43
+ # @param entity [Entity::Batch]
44
+ # @return [Entity::Batch]
45
+ # @raise [Error::Request]
46
+ def create(entity:)
47
+ data = connection.post(path: "/batches", body: entity.to_h)["data"]
48
+
49
+ Entity::Batch.new(attributes: data)
50
+ rescue Error::Request => e
51
+ raise Error::Request.new(response: e.response, message: "Request Unsuccessful: The batch #{entity.inspect} could not be created. FaithTeams API failure message: #{e.message}}") if e.response.status.success?
52
+ raise
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Resource
7
+ # A transaction in faithteams
8
+ class Contribution < Base
9
+ # @param entity [Entity::Contribution]
10
+ # @return [Entity::Contribution]
11
+ # @raise [Error::Request]
12
+ def create(entity:)
13
+ data = connection.post(path: "/contributions", body: entity.to_h)["data"]
14
+
15
+ Entity::Contribution.new(attributes: data)
16
+ rescue Error::Request => e
17
+ raise Error::Request.new(response: e.response, message: "Request Unsuccessful: The contribution #{entity.inspect} could not be created. FaithTeams API failure message: #{e.message}}") if e.response.status.success?
18
+ raise
19
+ end
20
+
21
+ # @param id [Integer] The contributions `parent_id`
22
+ # @return [Entity::Contribution, nil]
23
+ # @raise [Error::Request]
24
+ def find(id:)
25
+ raise FaithTeams::API::V2::Error::NoSearchParameterProvided if id.nil?
26
+
27
+ data = connection.get(path: "/contributions/#{id}")["data"]
28
+ return nil unless data.present?
29
+
30
+ Entity::Contribution.new(attributes: data)
31
+ rescue Error::Request => e
32
+ raise Error::Request.new(response: e.response, message: "Request Unsuccessful: The contribution with parent_id #{id} could not be found. FaithTeams API failure message: #{e.message}}") if e.response.status.success?
33
+ raise
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaithTeams
4
+ module API
5
+ module V2
6
+ module Resource
7
+ # The contribution type resource
8
+ class ContributionType < Base
9
+ # @param args [Hash] These are ignored as no filters are available for this endpoint
10
+ # @return [Entity::ContributionType]
11
+ def search(**args)
12
+ data = connection.get(path: "/contributiontypes", params: {}).fetch("data")
13
+
14
+ return nil unless data.present?
15
+
16
+ data.map do |record|
17
+ Entity::ContributionType.new(attributes: record)
18
+ end
19
+ end
20
+
21
+ # @param id [Integer]
22
+ # @return [Entity::ContributionType]
23
+ def find(id:)
24
+ return nil if id.blank?
25
+
26
+ data = connection.get(path: "/contributiontypes/#{id}", params: {}).fetch("data")
27
+
28
+ return nil unless data.present?
29
+
30
+ Entity::ContributionType.new(attributes: data)
31
+ rescue Error::Request => e
32
+ e.response.code == 404 ? nil : raise
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end