virtuous 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/test.yml +26 -0
- data/.gitignore +5 -0
- data/.reek.yml +36 -0
- data/.rubocop.yml +87 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +17 -0
- data/LICENSE +21 -0
- data/README.md +54 -0
- data/Rakefile +24 -0
- data/lib/virtuous/client/contact.rb +220 -0
- data/lib/virtuous/client/contact_address.rb +78 -0
- data/lib/virtuous/client/gift.rb +394 -0
- data/lib/virtuous/client/gift_designation.rb +59 -0
- data/lib/virtuous/client/individual.rb +125 -0
- data/lib/virtuous/client/recurring_gift.rb +86 -0
- data/lib/virtuous/client.rb +272 -0
- data/lib/virtuous/error.rb +54 -0
- data/lib/virtuous/helpers/hash_helper.rb +28 -0
- data/lib/virtuous/helpers/string_helper.rb +31 -0
- data/lib/virtuous/parse_oj.rb +24 -0
- data/lib/virtuous/version.rb +5 -0
- data/lib/virtuous.rb +12 -0
- data/logo/virtuous.svg +1 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/client_factory.rb +10 -0
- data/spec/support/fixtures/contact.json +112 -0
- data/spec/support/fixtures/contact_address.json +20 -0
- data/spec/support/fixtures/contact_addresses.json +42 -0
- data/spec/support/fixtures/contact_gifts.json +80 -0
- data/spec/support/fixtures/gift.json +55 -0
- data/spec/support/fixtures/gift_designation_query_options.json +2701 -0
- data/spec/support/fixtures/gift_designations.json +175 -0
- data/spec/support/fixtures/gifts.json +112 -0
- data/spec/support/fixtures/import.json +0 -0
- data/spec/support/fixtures/individual.json +46 -0
- data/spec/support/fixtures/recurring_gift.json +26 -0
- data/spec/support/fixtures_helper.rb +5 -0
- data/spec/support/virtuous_mock.rb +101 -0
- data/spec/virtuous/client_spec.rb +270 -0
- data/spec/virtuous/error_spec.rb +74 -0
- data/spec/virtuous/resources/contact_address_spec.rb +75 -0
- data/spec/virtuous/resources/contact_spec.rb +137 -0
- data/spec/virtuous/resources/gift_designation_spec.rb +70 -0
- data/spec/virtuous/resources/gift_spec.rb +249 -0
- data/spec/virtuous/resources/individual_spec.rb +95 -0
- data/spec/virtuous/resources/recurring_gift_spec.rb +67 -0
- data/spec/virtuous_spec.rb +7 -0
- data/virtuous.gemspec +25 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3c435c6a389b27d1644f8fa32d0df952aa9bcb83baf152973c8e2f55b0b418a1
|
4
|
+
data.tar.gz: 13075eb9634a01b1597c6a8be58444b1ec89738efe8842b124e4e640237163a4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 720aaf08ccabd9f7d1b7da3b07b4d028646c910c32605d85c4fe915050799eec9880b70f377674af848af13cab25fe18e92c3c6f460393499739188d5010ed29
|
7
|
+
data.tar.gz: 8b65f36c8bef728c092210f0448769b2d581d445755ca35d23eea6d1ae9e624bc9bad1602fa5edc4f0f45ac9920cf5f6c02b5877f07444366133422f9457d4bf
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Run specs
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
pull_request:
|
7
|
+
branches: [master]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- name: Set up Ruby
|
16
|
+
uses: ruby/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
bundler-cache: true
|
19
|
+
- name: Install dependencies
|
20
|
+
run: bundle install
|
21
|
+
- name: Lint
|
22
|
+
run: |
|
23
|
+
bundle exec rubocop
|
24
|
+
bundle exec reek
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rspec
|
data/.gitignore
ADDED
data/.reek.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
detectors:
|
2
|
+
IrresponsibleModule:
|
3
|
+
enabled: false
|
4
|
+
DataClump:
|
5
|
+
enabled: false
|
6
|
+
FeatureEnvy:
|
7
|
+
exclude:
|
8
|
+
- "Virtuous::Client#connection"
|
9
|
+
- "Virtuous::Client#unauthorized_connection"
|
10
|
+
- "Virtuous::HashHelper#self.deep_transform_keys"
|
11
|
+
- "FaradayMiddleware::ParseOj#on_complete"
|
12
|
+
NilCheck:
|
13
|
+
exclude:
|
14
|
+
- "Virtuous::Client#initialize"
|
15
|
+
UtilityFunction:
|
16
|
+
public_methods_only: true
|
17
|
+
NestedIterators:
|
18
|
+
exclude:
|
19
|
+
- "Virtuous::HashHelper#self.deep_transform_keys"
|
20
|
+
TooManyStatements:
|
21
|
+
exclude:
|
22
|
+
- "Virtuous::HashHelper#self.deep_transform_keys"
|
23
|
+
- "Virtuous::Client#connection"
|
24
|
+
- "Virtuous::Client#unauthorized_connection"
|
25
|
+
- "FaradayMiddleware::VirtuousErrorHandler#on_complete"
|
26
|
+
ControlParameter:
|
27
|
+
exclude:
|
28
|
+
- "Virtuous::Client#initialize"
|
29
|
+
NilCheck:
|
30
|
+
enabled: false
|
31
|
+
TooManyInstanceVariables:
|
32
|
+
exclude:
|
33
|
+
- "Virtuous::Client"
|
34
|
+
InstanceVariableAssumption:
|
35
|
+
exclude:
|
36
|
+
- "Virtuous::Client"
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# All cops
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.7
|
5
|
+
NewCops: "enable"
|
6
|
+
Exclude:
|
7
|
+
- "bin/*"
|
8
|
+
- "vendor/**/*"
|
9
|
+
|
10
|
+
# Layout cops
|
11
|
+
|
12
|
+
Layout/LineLength:
|
13
|
+
Max: 100
|
14
|
+
# To make it possible to copy or click on URIs in the code, we allow lines
|
15
|
+
# containing a URI to be longer than Max.
|
16
|
+
AllowURI: true
|
17
|
+
URISchemes:
|
18
|
+
- http
|
19
|
+
- https
|
20
|
+
|
21
|
+
# Metrics cops
|
22
|
+
|
23
|
+
Metrics/AbcSize:
|
24
|
+
# The ABC size is a calculated magnitude, so this number can be an Integer or
|
25
|
+
# a Float.
|
26
|
+
Max: 15
|
27
|
+
Exclude:
|
28
|
+
- lib/virtuous/error.rb
|
29
|
+
|
30
|
+
Metrics/BlockLength:
|
31
|
+
CountComments: false # count full line comments?
|
32
|
+
Max: 25
|
33
|
+
Exclude:
|
34
|
+
- config/**/*
|
35
|
+
- spec/**/*
|
36
|
+
|
37
|
+
Metrics/BlockNesting:
|
38
|
+
Max: 4
|
39
|
+
|
40
|
+
Metrics/ClassLength:
|
41
|
+
CountComments: false # count full line comments?
|
42
|
+
Max: 200
|
43
|
+
|
44
|
+
# Avoid complex methods.
|
45
|
+
Metrics/CyclomaticComplexity:
|
46
|
+
Max: 6
|
47
|
+
Exclude:
|
48
|
+
- lib/virtuous/error.rb
|
49
|
+
|
50
|
+
Metrics/MethodLength:
|
51
|
+
CountComments: false # count full line comments?
|
52
|
+
Max: 24
|
53
|
+
|
54
|
+
Metrics/ModuleLength:
|
55
|
+
CountComments: false # count full line comments?
|
56
|
+
Max: 200
|
57
|
+
|
58
|
+
Metrics/ParameterLists:
|
59
|
+
Max: 5
|
60
|
+
CountKeywordArgs: true
|
61
|
+
|
62
|
+
Metrics/PerceivedComplexity:
|
63
|
+
Max: 12
|
64
|
+
|
65
|
+
# Style cops
|
66
|
+
|
67
|
+
Style/Documentation:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
Style/FrozenStringLiteralComment:
|
71
|
+
Enabled: false
|
72
|
+
|
73
|
+
Style/ModuleFunction:
|
74
|
+
Enabled: false
|
75
|
+
|
76
|
+
Style/SymbolArray:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
# Lint cops
|
80
|
+
|
81
|
+
Lint/AmbiguousBlockAssociation:
|
82
|
+
Exclude:
|
83
|
+
- spec/**/*
|
84
|
+
|
85
|
+
Naming/MemoizedInstanceVariableName:
|
86
|
+
Exclude:
|
87
|
+
- lib/virtuous/client.rb
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.2
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- A Client class with support for api key and OAuth authentication
|
13
|
+
- Methods to find, create and update contacts
|
14
|
+
- Methods to find, create, update and delete individuals
|
15
|
+
- Methods to find, create, update and delete gifts
|
16
|
+
- Method query gift designations
|
17
|
+
|
18
|
+
[unreleased]: https://github.com/taylorbrooks/virtuous/compare/v0.0.0...HEAD
|
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
gemspec
|
6
|
+
|
7
|
+
gem 'bundler', '~> 2.3'
|
8
|
+
gem 'dotenv', '~> 2.8.1'
|
9
|
+
gem 'pry', '~> 0.14.2'
|
10
|
+
gem 'puma', '~> 6.4'
|
11
|
+
gem 'rake', '~> 12.3.3'
|
12
|
+
gem 'reek', '~> 6.1'
|
13
|
+
gem 'rspec', '~> 3.7'
|
14
|
+
gem 'rubocop', '~> 1.57'
|
15
|
+
gem 'sinatra', '~> 2.0'
|
16
|
+
gem 'webmock', '~> 3.1'
|
17
|
+
gem 'yard', '~> 0.9'
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2023 Taylor Brooks
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
<img src="./logo/virtuous.svg" width="200" />
|
2
|
+
|
3
|
+
# Virtuous Ruby Client ![example workflow](https://github.com/taylorbrooks/virtuous/actions/workflows/test.yml/badge.svg)
|
4
|
+
|
5
|
+
A Ruby wrapper for the Virtuous API
|
6
|
+
|
7
|
+
To get a general overview of Virtuous: https://virtuous.org
|
8
|
+
|
9
|
+
[RDocs](https://rubydoc.info/github/taylorbrooks/virtuous/master)
|
10
|
+
|
11
|
+
### Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# in your Gemfile
|
17
|
+
gem 'virtuous', '~> 0.0.1'
|
18
|
+
|
19
|
+
# then...
|
20
|
+
bundle install
|
21
|
+
```
|
22
|
+
|
23
|
+
### Usage
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# Authenticating with username and password
|
27
|
+
client = Virtuous::Client.new
|
28
|
+
client.authenticate(username: ..., password: ...)
|
29
|
+
|
30
|
+
# Authenticating with api keys
|
31
|
+
client = Virtuous::Client.new(api_key: ...)
|
32
|
+
|
33
|
+
# Find a specific contact
|
34
|
+
client.find_contact_by_email('gob@bluthco.com')
|
35
|
+
```
|
36
|
+
|
37
|
+
### History
|
38
|
+
|
39
|
+
View the [changelog](https://github.com/taylorbrooks/virtuous/blob/master/CHANGELOG.md)
|
40
|
+
|
41
|
+
This gem follows [Semantic Versioning](http://semver.org/)
|
42
|
+
|
43
|
+
### Contributing
|
44
|
+
|
45
|
+
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
46
|
+
|
47
|
+
- [Report bugs](https://github.com/taylorbrooks/virtuous/issues)
|
48
|
+
- Fix bugs and [submit pull requests](https://github.com/taylorbrooks/virtuous/pulls)
|
49
|
+
- Write, clarify, or fix documentation
|
50
|
+
- Suggest or add new features
|
51
|
+
|
52
|
+
### Copyright
|
53
|
+
|
54
|
+
Copyright (c) 2018 Taylor Brooks. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task default: :spec
|
7
|
+
|
8
|
+
task :environment do
|
9
|
+
require 'dotenv'
|
10
|
+
Dotenv.load
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
13
|
+
require 'virtuous'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Launch a pry shell with libraries loaded'
|
17
|
+
task pry: :environment do
|
18
|
+
options = {}
|
19
|
+
options[:logger] = Logger.new($stdout) unless ENV['CLIENT_LOGGER'].nil?
|
20
|
+
@client = Virtuous::Client.new(**options) if ENV['VIRTUOUS_KEY']
|
21
|
+
|
22
|
+
require 'pry'
|
23
|
+
Pry.start
|
24
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
module Virtuous
|
2
|
+
class Client
|
3
|
+
##
|
4
|
+
# ### Contact data
|
5
|
+
#
|
6
|
+
# {
|
7
|
+
# contact_type: [String],
|
8
|
+
# reference_source: [String],
|
9
|
+
# reference_id: [String],
|
10
|
+
# name: [String],
|
11
|
+
# informal_name: [String],
|
12
|
+
# description: [String],
|
13
|
+
# website: [String],
|
14
|
+
# marital_status: [String],
|
15
|
+
# anniversary_month: [Integer],
|
16
|
+
# anniversary_day: [Integer],
|
17
|
+
# anniversary_year: [Integer],
|
18
|
+
# origin_segment_id: [Integer],
|
19
|
+
# is_private: [Boolean],
|
20
|
+
# is_archived: [Boolean],
|
21
|
+
# contact_addresses: [
|
22
|
+
# {
|
23
|
+
# label: [String],
|
24
|
+
# address1: [String],
|
25
|
+
# address2: [String],
|
26
|
+
# city: [String],
|
27
|
+
# state_code: [String],
|
28
|
+
# postal: [String],
|
29
|
+
# country_code: [String],
|
30
|
+
# is_primary: [Boolean],
|
31
|
+
# latitude: [Float],
|
32
|
+
# longitude: [Float]
|
33
|
+
# }
|
34
|
+
# ],
|
35
|
+
# contact_individuals: [
|
36
|
+
# {
|
37
|
+
# first_name: [String],
|
38
|
+
# last_name: [String],
|
39
|
+
# prefix: [String],
|
40
|
+
# middle_name: [String],
|
41
|
+
# suffix: [String],
|
42
|
+
# birth_month: [Integer],
|
43
|
+
# birth_day: [Integer],
|
44
|
+
# birth_year: [Integer],
|
45
|
+
# approximate_age: [Integer],
|
46
|
+
# gender: [String],
|
47
|
+
# passion: [String],
|
48
|
+
# is_primary: [Boolean],
|
49
|
+
# is_secondary: [Boolean],
|
50
|
+
# is_deceased: [Boolean],
|
51
|
+
# contact_methods: [
|
52
|
+
# {
|
53
|
+
# type: [String],
|
54
|
+
# value: [String],
|
55
|
+
# is_opted_in: [Boolean],
|
56
|
+
# is_primary: [Boolean]
|
57
|
+
# }
|
58
|
+
# ],
|
59
|
+
# custom_fields: [Hash]
|
60
|
+
# }
|
61
|
+
# ],
|
62
|
+
# custom_fields: [Hash],
|
63
|
+
# custom_collections: [
|
64
|
+
# {
|
65
|
+
# name: [String],
|
66
|
+
# fields: [
|
67
|
+
# {
|
68
|
+
# name: [String],
|
69
|
+
# value: [String]
|
70
|
+
# }
|
71
|
+
# ]
|
72
|
+
# }
|
73
|
+
# ]
|
74
|
+
# }
|
75
|
+
#
|
76
|
+
module Contact
|
77
|
+
##
|
78
|
+
# Fetches a contact record by email.
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# client.find_contact_by_email('contact@email.com')
|
82
|
+
#
|
83
|
+
# @param email [String] The email of the contact.
|
84
|
+
#
|
85
|
+
# @return [Hash] The contact information in a hash.
|
86
|
+
def find_contact_by_email(email)
|
87
|
+
parse(get('api/Contact/Find', { email: email }))
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Fetches a contact record by id.
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# client.get_contact(1)
|
95
|
+
#
|
96
|
+
# @param id [Integer] The id of the contact.
|
97
|
+
#
|
98
|
+
# @return [Hash] The contact information in a hash.
|
99
|
+
def get_contact(id)
|
100
|
+
parse(get("api/Contact/#{id}"))
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Creates a contact. This will use the virtuous import tool to match the new contact
|
105
|
+
# with existing ones. If the contact record exists already but there is new
|
106
|
+
# information the record will be flagged for review.
|
107
|
+
#
|
108
|
+
# Transactions are posted to the API and are set to a holding state.
|
109
|
+
# At midnight, transactions are bundled into imports based on the source they were posted
|
110
|
+
# with.
|
111
|
+
# The organization reviews the imported transactions, and then clicks run.
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
# client.import_contact(
|
115
|
+
# contact_type: 'Organization', name: 'Org name',
|
116
|
+
# first_name: 'John', last_name: 'Doe'
|
117
|
+
# )
|
118
|
+
#
|
119
|
+
# @param data [Hash] A hash containing the contact details.
|
120
|
+
#
|
121
|
+
# #### Required fields
|
122
|
+
# - `contact_type`: "Household", "Organization", "Foundation" or a custom type.
|
123
|
+
# - `contact_name`: required if Organization or Foundation.
|
124
|
+
# - `first_name`
|
125
|
+
# - `last_name`
|
126
|
+
#
|
127
|
+
# #### Suggested fields
|
128
|
+
# - `reference_source`: the system it came from.
|
129
|
+
# - `reference_id`: the ID in the original system.
|
130
|
+
# - `email`
|
131
|
+
# - `phone`
|
132
|
+
# - `address`
|
133
|
+
#
|
134
|
+
# #### Full list of accepted fields
|
135
|
+
#
|
136
|
+
# {
|
137
|
+
# reference_source: [String],
|
138
|
+
# reference_id: [String],
|
139
|
+
# contact_type: [String],
|
140
|
+
# name: [String],
|
141
|
+
# title: [String],
|
142
|
+
# first_name: [String],
|
143
|
+
# middle_name: [String],
|
144
|
+
# last_name: [String],
|
145
|
+
# suffix: [String],
|
146
|
+
# email_type: [String],
|
147
|
+
# email: [String],
|
148
|
+
# phone_type: [String],
|
149
|
+
# phone: [String],
|
150
|
+
# address1: [String],
|
151
|
+
# address2: [String],
|
152
|
+
# city: [String],
|
153
|
+
# state: [String],
|
154
|
+
# postal: [String],
|
155
|
+
# country: [String],
|
156
|
+
# event_id: [Integer],
|
157
|
+
# event_name: [String],
|
158
|
+
# invited: [Boolean],
|
159
|
+
# rsvp: [Boolean],
|
160
|
+
# rsvp_response: [Boolean],
|
161
|
+
# attended: [Boolean],
|
162
|
+
# tags: [String],
|
163
|
+
# origin_segment_code: [String],
|
164
|
+
# email_lists: [String[]],
|
165
|
+
# custom_fields: [Hash],
|
166
|
+
# volunteer_attendances: [
|
167
|
+
# {
|
168
|
+
# volunteer_opportunity_id: [Integer],
|
169
|
+
# volunteer_opportunity_name: [String],
|
170
|
+
# date: [String],
|
171
|
+
# hours: [String]
|
172
|
+
# }
|
173
|
+
# ]
|
174
|
+
# }
|
175
|
+
#
|
176
|
+
def import_contact(data)
|
177
|
+
post('api/Contact/Transaction', format(data))
|
178
|
+
end
|
179
|
+
|
180
|
+
##
|
181
|
+
# Creates a contact.
|
182
|
+
#
|
183
|
+
# @example
|
184
|
+
# client.create_contact(
|
185
|
+
# contact_type: 'Organization', name: 'Org name',
|
186
|
+
# contact_individuals: [
|
187
|
+
# { first_name: 'John', last_name: 'Doe' }
|
188
|
+
# ]
|
189
|
+
# )
|
190
|
+
#
|
191
|
+
# @param data [Hash] A hash containing the contact details.
|
192
|
+
# Refer to the [Contact data](#label-Contact+data) section
|
193
|
+
# above to see the available attributes.
|
194
|
+
#
|
195
|
+
# @return [Hash] The contact that has been created.
|
196
|
+
def create_contact(data)
|
197
|
+
parse(post('api/Contact', format(data)))
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# Updates a contact.
|
202
|
+
#
|
203
|
+
# @example
|
204
|
+
# client.update_contact(1, contact_type: 'Organization', name: 'New name')
|
205
|
+
#
|
206
|
+
# @note Excluding a property will remove it's value from the object.
|
207
|
+
# If you're only updating a single property, the entire model is still required.
|
208
|
+
#
|
209
|
+
# @param id [Integer] The id of the contact to update.
|
210
|
+
# @param data [Hash] A hash containing the contact details.
|
211
|
+
# Refer to the [Contact data](#label-Contact+data) section
|
212
|
+
# above to see the available attributes.
|
213
|
+
#
|
214
|
+
# @return [Hash] The contact that has been updated.
|
215
|
+
def update_contact(id, data)
|
216
|
+
parse(put("api/Contact/#{id}", format(data)))
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Virtuous
|
2
|
+
class Client
|
3
|
+
##
|
4
|
+
# ### Contact Address data
|
5
|
+
#
|
6
|
+
# {
|
7
|
+
# contact_id: [Integer],
|
8
|
+
# label: [String],
|
9
|
+
# address1: [String],
|
10
|
+
# address2: [String],
|
11
|
+
# city: [String],
|
12
|
+
# state: [String],
|
13
|
+
# postal: [String],
|
14
|
+
# country: [String],
|
15
|
+
# set_as_primary: [Boolean],
|
16
|
+
# start_month: [Integer],
|
17
|
+
# start_day: [Integer],
|
18
|
+
# end_month: [Integer],
|
19
|
+
# end_day: [Integer]
|
20
|
+
# }
|
21
|
+
#
|
22
|
+
module ContactAddress
|
23
|
+
##
|
24
|
+
# Gets the addresses of a contact.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# client.get_contact_addresses(1)
|
28
|
+
#
|
29
|
+
# @param contact_id [Integer] The id of the Contact.
|
30
|
+
#
|
31
|
+
# @return [Array] An array with all the addresses of a contact.
|
32
|
+
#
|
33
|
+
def get_contact_addresses(contact_id)
|
34
|
+
response = get("api/ContactAddress/ByContact/#{contact_id}")
|
35
|
+
response.map { |address| parse(address) }
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Updates an address.
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# client.update_contact_address(
|
43
|
+
# 1, label: 'Home address', address1: '324 Frank Island', address2: 'Apt. 366',
|
44
|
+
# city: 'Antonioborough', state: 'Massachusetts', postal: '27516', country: 'USA'
|
45
|
+
# )
|
46
|
+
#
|
47
|
+
# @note Excluding a property will remove it's value from the object.
|
48
|
+
# If you're only updating a single property, the entire model is still required.
|
49
|
+
#
|
50
|
+
# @param id [Integer] The id of the address to update.
|
51
|
+
# @param data [Hash] A hash containing the address details.
|
52
|
+
# Refer to the data section above to see the available attributes.
|
53
|
+
#
|
54
|
+
# @return [Hash] The address that has been updated.
|
55
|
+
def update_contact_address(id, data)
|
56
|
+
parse(put("api/ContactAddress/#{id}", format(data)))
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Creates an address.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# client.create_contact_address(
|
64
|
+
# contact_id: 1, label: 'Home address', address1: '324 Frank Island',
|
65
|
+
# address2: 'Apt. 366', city: 'Antonioborough', state: 'Massachusetts', postal: '27516',
|
66
|
+
# country: 'USA'
|
67
|
+
# )
|
68
|
+
#
|
69
|
+
# @param data [Hash] A hash containing the address details.
|
70
|
+
# Refer to the data section above to see the available attributes.
|
71
|
+
#
|
72
|
+
# @return [Hash] The address that has been created.
|
73
|
+
def create_contact_address(data)
|
74
|
+
parse(post('api/ContactAddress', format(data)))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|