vantaca 0.3.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +30 -0
- data/.rubocop.yml +58 -0
- data/.vscode/settings.json +14 -0
- data/Gemfile +35 -0
- data/Gemfile.lock +153 -0
- data/README.md +3 -0
- data/Rakefile +11 -0
- data/lib/vantaca/action_items.rb +28 -0
- data/lib/vantaca/addresses.rb +21 -0
- data/lib/vantaca/client.rb +109 -0
- data/lib/vantaca/communities.rb +47 -0
- data/lib/vantaca/configuration.rb +43 -0
- data/lib/vantaca/documents.rb +25 -0
- data/lib/vantaca/emails.rb +35 -0
- data/lib/vantaca/errors.rb +53 -0
- data/lib/vantaca/ledger.rb +28 -0
- data/lib/vantaca/models/action_category.rb +17 -0
- data/lib/vantaca/models/action_type.rb +24 -0
- data/lib/vantaca/models/address.rb +55 -0
- data/lib/vantaca/models/base.rb +21 -0
- data/lib/vantaca/models/community.rb +21 -0
- data/lib/vantaca/models/document.rb +21 -0
- data/lib/vantaca/models/email.rb +27 -0
- data/lib/vantaca/models/owner.rb +61 -0
- data/lib/vantaca/models/phone.rb +27 -0
- data/lib/vantaca/models/provider.rb +58 -0
- data/lib/vantaca/models/provider_insurance.rb +40 -0
- data/lib/vantaca/owners.rb +131 -0
- data/lib/vantaca/phones.rb +35 -0
- data/lib/vantaca/providers.rb +61 -0
- data/lib/vantaca/version.rb +8 -0
- data/lib/vantaca.rb +28 -0
- data/vantaca.gemspec +30 -0
- metadata +101 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 17d644bafa17b33e40ce3695a575773dc6a4c32500b20463e5a85849d9e7f7ce
|
|
4
|
+
data.tar.gz: 1d1644fde830360cec3b38860f124528a32411613b5d0d4693866f01f2984bcf
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 69c22312ab4573a406982fed1c14ada85cc2bbeed1b4dbc197266ffda5e6b07d924588575739feeb6b1887a7c04b916b53d7017dde71cfce1712cd6b3959c9fe
|
|
7
|
+
data.tar.gz: 205fef825382c52847c32aa83d8ae304cd7bd74372e40602e22aa97fbcb3af181ae1a3eb7c5169d077bdc350d42ac9c0bdf173bd2ab428a3b322a6a474e92093
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: RSpec
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ ubuntu ]
|
|
15
|
+
ruby: [ 4.0, head ]
|
|
16
|
+
|
|
17
|
+
runs-on: ${{ matrix.os }}-latest
|
|
18
|
+
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v2
|
|
22
|
+
- name: Set up Ruby
|
|
23
|
+
uses: ruby/setup-ruby@v1
|
|
24
|
+
with:
|
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
|
26
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically:
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: bundle install
|
|
29
|
+
- name: Run tests
|
|
30
|
+
run: bundle exec rake
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-rake
|
|
3
|
+
|
|
4
|
+
AllCops:
|
|
5
|
+
TargetRubyVersion: 4.0
|
|
6
|
+
# Always enable new cops, disabling manually when they don't fit.
|
|
7
|
+
EnabledByDefault: true
|
|
8
|
+
NewCops: enable
|
|
9
|
+
|
|
10
|
+
# ------------------------------------------------------------------------------
|
|
11
|
+
# Cops excluded for specific directories
|
|
12
|
+
# ------------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
Metrics/BlockLength:
|
|
15
|
+
Exclude:
|
|
16
|
+
- 'spec/**/*'
|
|
17
|
+
|
|
18
|
+
Style/Copyright:
|
|
19
|
+
AutocorrectNotice: |
|
|
20
|
+
# Copyright (c) Valencia Management Group
|
|
21
|
+
# All rights reserved.
|
|
22
|
+
Notice: |
|
|
23
|
+
Copyright \(c\) Valencia Management Group
|
|
24
|
+
All rights reserved.
|
|
25
|
+
|
|
26
|
+
# ------------------------------------------------------------------------------
|
|
27
|
+
# Cops that should not be run
|
|
28
|
+
# ------------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
Layout/MultilineMethodArgumentLineBreaks:
|
|
31
|
+
Enabled: false
|
|
32
|
+
|
|
33
|
+
# Recommends `::File` instead of `File`
|
|
34
|
+
Lint/ConstantResolution:
|
|
35
|
+
Enabled: false
|
|
36
|
+
|
|
37
|
+
# Recommends Integer(xxx, 10) instead of xxx.to_i
|
|
38
|
+
Lint/NumberConversion:
|
|
39
|
+
Enabled: false
|
|
40
|
+
|
|
41
|
+
Style/ConstantVisibility:
|
|
42
|
+
Enabled: false
|
|
43
|
+
|
|
44
|
+
# Every method should be documented, but I'm not *that* professional.
|
|
45
|
+
Style/DocumentationMethod:
|
|
46
|
+
Enabled: false
|
|
47
|
+
|
|
48
|
+
# Converts `.to eq 1` to `.to(eq(1))`
|
|
49
|
+
Style/MethodCallWithArgsParentheses:
|
|
50
|
+
Enabled: false
|
|
51
|
+
|
|
52
|
+
# This is just for setting HTTParty's request headers
|
|
53
|
+
Style/StringHashKeys:
|
|
54
|
+
Enabled: false
|
|
55
|
+
|
|
56
|
+
# Forbids the use of "rubocop:disable"
|
|
57
|
+
Style/DisableCopsWithinSourceCodeDirective:
|
|
58
|
+
Enabled: false
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"[ruby]": {
|
|
3
|
+
"editor.rulers": [120],
|
|
4
|
+
"editor.tabSize": 2,
|
|
5
|
+
},
|
|
6
|
+
"[yaml]": {
|
|
7
|
+
"editor.rulers": [120],
|
|
8
|
+
"editor.tabSize": 2,
|
|
9
|
+
},
|
|
10
|
+
"files.insertFinalNewline": true,
|
|
11
|
+
"files.trimTrailingWhitespace": true,
|
|
12
|
+
"ruby.intellisense": false,
|
|
13
|
+
"ruby.useLanguageServer": true
|
|
14
|
+
}
|
data/Gemfile
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
source 'https://rubygems.org'
|
|
7
|
+
|
|
8
|
+
gemspec
|
|
9
|
+
|
|
10
|
+
# Gem management
|
|
11
|
+
gem 'bundler', '~> 4.0'
|
|
12
|
+
|
|
13
|
+
# Deployment tasks
|
|
14
|
+
gem 'rake', '~> 13.0'
|
|
15
|
+
|
|
16
|
+
# Test with RSpec
|
|
17
|
+
gem 'rspec', '~> 3.12'
|
|
18
|
+
|
|
19
|
+
# Ruby code linting
|
|
20
|
+
gem 'rubocop', '~> 1.54'
|
|
21
|
+
|
|
22
|
+
# Rubocop - rake cops
|
|
23
|
+
gem 'rubocop-rake', '~> 0.6'
|
|
24
|
+
|
|
25
|
+
# Rubocop - rspec cops
|
|
26
|
+
gem 'rubocop-rspec', '~> 3.0'
|
|
27
|
+
|
|
28
|
+
# Replay full HTTP interactions
|
|
29
|
+
gem 'vcr', '~> 6.2'
|
|
30
|
+
|
|
31
|
+
# Mock HTTP requests so that we're not hitting the actual Vantaca servers
|
|
32
|
+
gem 'webmock', '~> 3.18'
|
|
33
|
+
|
|
34
|
+
# Output logging
|
|
35
|
+
gem 'logger', '~> 1.7'
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
vantaca (0.3.0)
|
|
5
|
+
httparty (~> 0.24)
|
|
6
|
+
zeitwerk (~> 2.7)
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
addressable (2.8.9)
|
|
12
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
13
|
+
ast (2.4.3)
|
|
14
|
+
bigdecimal (4.0.1)
|
|
15
|
+
crack (1.0.1)
|
|
16
|
+
bigdecimal
|
|
17
|
+
rexml
|
|
18
|
+
csv (3.3.5)
|
|
19
|
+
diff-lcs (1.6.2)
|
|
20
|
+
hashdiff (1.2.1)
|
|
21
|
+
httparty (0.24.2)
|
|
22
|
+
csv
|
|
23
|
+
mini_mime (>= 1.0.0)
|
|
24
|
+
multi_xml (>= 0.5.2)
|
|
25
|
+
json (2.19.1)
|
|
26
|
+
json-schema (6.2.0)
|
|
27
|
+
addressable (~> 2.8)
|
|
28
|
+
bigdecimal (>= 3.1, < 5)
|
|
29
|
+
language_server-protocol (3.17.0.5)
|
|
30
|
+
lint_roller (1.1.0)
|
|
31
|
+
logger (1.7.0)
|
|
32
|
+
mcp (0.8.0)
|
|
33
|
+
json-schema (>= 4.1)
|
|
34
|
+
mini_mime (1.1.5)
|
|
35
|
+
multi_xml (0.8.1)
|
|
36
|
+
bigdecimal (>= 3.1, < 5)
|
|
37
|
+
parallel (1.27.0)
|
|
38
|
+
parser (3.3.10.2)
|
|
39
|
+
ast (~> 2.4.1)
|
|
40
|
+
racc
|
|
41
|
+
prism (1.9.0)
|
|
42
|
+
public_suffix (7.0.5)
|
|
43
|
+
racc (1.8.1)
|
|
44
|
+
rainbow (3.1.1)
|
|
45
|
+
rake (13.3.1)
|
|
46
|
+
regexp_parser (2.11.3)
|
|
47
|
+
rexml (3.4.4)
|
|
48
|
+
rspec (3.13.2)
|
|
49
|
+
rspec-core (~> 3.13.0)
|
|
50
|
+
rspec-expectations (~> 3.13.0)
|
|
51
|
+
rspec-mocks (~> 3.13.0)
|
|
52
|
+
rspec-core (3.13.6)
|
|
53
|
+
rspec-support (~> 3.13.0)
|
|
54
|
+
rspec-expectations (3.13.5)
|
|
55
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
56
|
+
rspec-support (~> 3.13.0)
|
|
57
|
+
rspec-mocks (3.13.8)
|
|
58
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
59
|
+
rspec-support (~> 3.13.0)
|
|
60
|
+
rspec-support (3.13.7)
|
|
61
|
+
rubocop (1.85.1)
|
|
62
|
+
json (~> 2.3)
|
|
63
|
+
language_server-protocol (~> 3.17.0.2)
|
|
64
|
+
lint_roller (~> 1.1.0)
|
|
65
|
+
mcp (~> 0.6)
|
|
66
|
+
parallel (~> 1.10)
|
|
67
|
+
parser (>= 3.3.0.2)
|
|
68
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
69
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
70
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
71
|
+
ruby-progressbar (~> 1.7)
|
|
72
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
73
|
+
rubocop-ast (1.49.1)
|
|
74
|
+
parser (>= 3.3.7.2)
|
|
75
|
+
prism (~> 1.7)
|
|
76
|
+
rubocop-rake (0.7.1)
|
|
77
|
+
lint_roller (~> 1.1)
|
|
78
|
+
rubocop (>= 1.72.1)
|
|
79
|
+
rubocop-rspec (3.9.0)
|
|
80
|
+
lint_roller (~> 1.1)
|
|
81
|
+
rubocop (~> 1.81)
|
|
82
|
+
ruby-progressbar (1.13.0)
|
|
83
|
+
unicode-display_width (3.2.0)
|
|
84
|
+
unicode-emoji (~> 4.1)
|
|
85
|
+
unicode-emoji (4.2.0)
|
|
86
|
+
vcr (6.4.0)
|
|
87
|
+
webmock (3.26.1)
|
|
88
|
+
addressable (>= 2.8.0)
|
|
89
|
+
crack (>= 0.3.2)
|
|
90
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
91
|
+
zeitwerk (2.7.5)
|
|
92
|
+
|
|
93
|
+
PLATFORMS
|
|
94
|
+
arm64-darwin-25
|
|
95
|
+
ruby
|
|
96
|
+
|
|
97
|
+
DEPENDENCIES
|
|
98
|
+
bundler (~> 4.0)
|
|
99
|
+
logger (~> 1.7)
|
|
100
|
+
rake (~> 13.0)
|
|
101
|
+
rspec (~> 3.12)
|
|
102
|
+
rubocop (~> 1.54)
|
|
103
|
+
rubocop-rake (~> 0.6)
|
|
104
|
+
rubocop-rspec (~> 3.0)
|
|
105
|
+
vantaca!
|
|
106
|
+
vcr (~> 6.2)
|
|
107
|
+
webmock (~> 3.18)
|
|
108
|
+
|
|
109
|
+
CHECKSUMS
|
|
110
|
+
addressable (2.8.9) sha256=cc154fcbe689711808a43601dee7b980238ce54368d23e127421753e46895485
|
|
111
|
+
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
112
|
+
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
|
|
113
|
+
crack (1.0.1) sha256=ff4a10390cd31d66440b7524eb1841874db86201d5b70032028553130b6d4c7e
|
|
114
|
+
csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f
|
|
115
|
+
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
116
|
+
hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1
|
|
117
|
+
httparty (0.24.2) sha256=8fca6a54aa0c4aa4303a0fd33e5e2156175d6a5334f714263b458abd7fda9c38
|
|
118
|
+
json (2.19.1) sha256=dd94fdc59e48bff85913829a32350b3148156bc4fd2a95a2568a78b11344082d
|
|
119
|
+
json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666
|
|
120
|
+
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
|
|
121
|
+
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
122
|
+
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
123
|
+
mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb
|
|
124
|
+
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
|
|
125
|
+
multi_xml (0.8.1) sha256=addba0290bac34e9088bfe73dc4878530297a82a7bbd66cb44dcd0a4b86edf5a
|
|
126
|
+
parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
|
|
127
|
+
parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357
|
|
128
|
+
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
129
|
+
public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623
|
|
130
|
+
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
131
|
+
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
|
|
132
|
+
rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
|
|
133
|
+
regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
|
|
134
|
+
rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
|
|
135
|
+
rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
|
|
136
|
+
rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
|
|
137
|
+
rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
|
|
138
|
+
rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
|
|
139
|
+
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
|
|
140
|
+
rubocop (1.85.1) sha256=3dbcf9e961baa4c376eeeb2a03913dca5e3987033b04d38fa538aa1e7406cc77
|
|
141
|
+
rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
|
|
142
|
+
rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
|
|
143
|
+
rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2
|
|
144
|
+
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
|
|
145
|
+
unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
|
|
146
|
+
unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
|
|
147
|
+
vantaca (0.3.0)
|
|
148
|
+
vcr (6.4.0) sha256=077ac92cc16efc5904eb90492a18153b5e6ca5398046d8a249a7c96a9ea24ae6
|
|
149
|
+
webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7
|
|
150
|
+
zeitwerk (2.7.5) sha256=d8da92128c09ea6ec62c949011b00ed4a20242b255293dd66bf41545398f73dd
|
|
151
|
+
|
|
152
|
+
BUNDLED WITH
|
|
153
|
+
4.0.6
|
data/README.md
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
# Methods which interact with Action Items
|
|
8
|
+
module ActionItems
|
|
9
|
+
# Load all active action categories.
|
|
10
|
+
#
|
|
11
|
+
# @return [Array<Vantaca::Models::ActionCategory>] active action categories
|
|
12
|
+
def action_categories
|
|
13
|
+
response = get('/read/actionCategoryList')
|
|
14
|
+
|
|
15
|
+
return [] unless response
|
|
16
|
+
|
|
17
|
+
Array(response).map { Vantaca::Models::ActionCategory.new(it) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def action_types
|
|
21
|
+
response = get('/read/actionTypeList')
|
|
22
|
+
|
|
23
|
+
return [] unless response
|
|
24
|
+
|
|
25
|
+
Array(response).map { Vantaca::Models::ActionType.new(it) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
# Methods which allow creation, modification, and deletion of homeowner addresses.
|
|
8
|
+
module Addresses
|
|
9
|
+
def create_address(homeowner_id, address_attributes)
|
|
10
|
+
post('/write/addressCreate', address_attributes.merge(hoid: homeowner_id))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def update_address(address_id, address_attributes)
|
|
14
|
+
post('/write/addressUpdate', address_attributes.merge(addrID: address_id))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def delete_address(address_id)
|
|
18
|
+
post('/write/addressDestroy', { addrID: address_id })
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
require 'logger'
|
|
7
|
+
|
|
8
|
+
module Vantaca
|
|
9
|
+
# The client which enables communication with the Vantaca API
|
|
10
|
+
class Client
|
|
11
|
+
include HTTParty
|
|
12
|
+
|
|
13
|
+
include Vantaca::ActionItems
|
|
14
|
+
include Vantaca::Addresses
|
|
15
|
+
include Vantaca::Communities
|
|
16
|
+
include Vantaca::Documents
|
|
17
|
+
include Vantaca::Emails
|
|
18
|
+
include Vantaca::Ledger
|
|
19
|
+
include Vantaca::Owners
|
|
20
|
+
include Vantaca::Phones
|
|
21
|
+
include Vantaca::Providers
|
|
22
|
+
|
|
23
|
+
headers 'Content-Type' => 'application/json'
|
|
24
|
+
|
|
25
|
+
base_uri 'https://service-e.vantaca.net/'
|
|
26
|
+
|
|
27
|
+
attr_accessor :logger
|
|
28
|
+
|
|
29
|
+
def initialize(logger: IO::NULL)
|
|
30
|
+
@logger = logger_for(logger)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def get(endpoint, **query)
|
|
34
|
+
response = self.class.get endpoint, query: query.merge(default_params)
|
|
35
|
+
|
|
36
|
+
raise_exception(response) unless (200..299).include? response.code
|
|
37
|
+
|
|
38
|
+
response.parsed_response
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def put(endpoint, body, **query)
|
|
42
|
+
response = self.class.put endpoint, query: query.merge(default_params), body: body.to_json
|
|
43
|
+
|
|
44
|
+
raise_exception(response) unless response.code == 200
|
|
45
|
+
|
|
46
|
+
response.parsed_response
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def post(endpoint, body, **query)
|
|
50
|
+
response = self.class.post endpoint, query: query.merge(default_params), body: body.to_json
|
|
51
|
+
|
|
52
|
+
raise_exception(response) unless response.code == 200
|
|
53
|
+
|
|
54
|
+
# This is always going to be `nil` for POST requests, but it doesn't hurt to be consistent.
|
|
55
|
+
response.parsed_response
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def download(endpoint, **params)
|
|
59
|
+
raise ArgumentError, 'Vantaca::Client#download requires a block' unless block_given?
|
|
60
|
+
|
|
61
|
+
Tempfile.open('download') do |file|
|
|
62
|
+
file.binmode
|
|
63
|
+
|
|
64
|
+
file.write download_raw_data(endpoint, **params)
|
|
65
|
+
|
|
66
|
+
yield file
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
protected
|
|
71
|
+
|
|
72
|
+
def default_params = Vantaca.configuration.to_params
|
|
73
|
+
|
|
74
|
+
def raise_exception(response)
|
|
75
|
+
case response.code
|
|
76
|
+
when 404 then raise Vantaca::Errors::NotFoundError, response
|
|
77
|
+
when 400..499 then raise Vantaca::Errors::ClientError, response
|
|
78
|
+
when 500..599
|
|
79
|
+
# These errors can largely be ignored - it's not our fault
|
|
80
|
+
raise Vantaca::Errors::TimeoutError, response if response.response.message['Timeout expired']
|
|
81
|
+
|
|
82
|
+
raise Vantaca::Errors::InternalError, response
|
|
83
|
+
else
|
|
84
|
+
# As far as I'm aware, Vantaca does not return 100 - 199 or 205 - 399.
|
|
85
|
+
raise Vantaca::Errors::ApiError, response
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def download_raw_data(endpoint, **query)
|
|
90
|
+
response = self.class.get(
|
|
91
|
+
endpoint,
|
|
92
|
+
headers: { 'Content-Type' => 'application/octet-stream' },
|
|
93
|
+
query: query.merge(default_params)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
raise_exception(response) unless response.code == 200
|
|
97
|
+
|
|
98
|
+
response
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def logger_for(logger)
|
|
102
|
+
return logger if logger.is_a?(::Logger)
|
|
103
|
+
|
|
104
|
+
return Vantaca.configuration.logger if logger == IO::NULL && Vantaca.configuration.logger
|
|
105
|
+
|
|
106
|
+
::Logger.new(logger)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
# Methods which load general information, but not owners, of one or more communities.
|
|
8
|
+
module Communities
|
|
9
|
+
COMMUNITY_PARAMETERS = { charges: :includeCharges, late_fees: :includeLateFees }.freeze
|
|
10
|
+
|
|
11
|
+
# Load a list of all communities actively managed.
|
|
12
|
+
#
|
|
13
|
+
# @return [Array<Vantaca::Models::Community>] An array of all communities managed.
|
|
14
|
+
def communities(**options)
|
|
15
|
+
params = community_parameters(nil, options)
|
|
16
|
+
|
|
17
|
+
get('/read/Association', **params).map { Vantaca::Models::Community.new(it) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Load a single community by its abbreviation.
|
|
21
|
+
#
|
|
22
|
+
# @param assoc_code [String] The 2-4 character association code of the community
|
|
23
|
+
# @return [Vantaca::Models::Community] The community with the indicated association code.
|
|
24
|
+
def community(assoc_code, **options)
|
|
25
|
+
params = community_parameters(assoc_code, options)
|
|
26
|
+
|
|
27
|
+
response = get('/read/Association', **params)
|
|
28
|
+
|
|
29
|
+
# The API sends a 204 No Content response if there's no matching community.
|
|
30
|
+
raise Vantaca::Errors::NotFoundError unless response
|
|
31
|
+
|
|
32
|
+
Vantaca::Models::Community.new response.first
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
def community_parameters(community, options)
|
|
38
|
+
params = { assocCode: community }
|
|
39
|
+
|
|
40
|
+
COMMUNITY_PARAMETERS.values_at(*Array(options[:include])).compact.each do |vantaca_parameter|
|
|
41
|
+
params[vantaca_parameter] = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
params.compact
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
# The basic configuration object for the Vantaca client. I wish these weren't passed in the URL...
|
|
8
|
+
class Configuration
|
|
9
|
+
attr_reader :login, :password, :company, :logger
|
|
10
|
+
|
|
11
|
+
def company=(input)
|
|
12
|
+
raise ArgumentError, 'Invalid Vantaca company name' unless input&.match?(/\A\w+\z/)
|
|
13
|
+
|
|
14
|
+
@company = input
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def login=(input)
|
|
18
|
+
raise ArgumentError, 'Invalid Vantaca login' unless input&.match?(/\A\w+\z/)
|
|
19
|
+
|
|
20
|
+
@login = input
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def password=(input)
|
|
24
|
+
raise ArgumentError, 'Invalid Vantaca password' unless input&.match?(/\A\w+\z/)
|
|
25
|
+
|
|
26
|
+
@password = input
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def logger=(new_logger)
|
|
30
|
+
raise ArgumentError, 'Logger must be an instance of the Logger class' unless new_logger.is_a?(::Logger)
|
|
31
|
+
|
|
32
|
+
@logger = new_logger
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_params
|
|
36
|
+
{
|
|
37
|
+
company: @company,
|
|
38
|
+
login: @login,
|
|
39
|
+
pwd: @password
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
# Methods which fetch lists of documents or a document itself
|
|
8
|
+
module Documents
|
|
9
|
+
def documents(community:)
|
|
10
|
+
response = get('/read/Association', assocCode: community, includeDocuments: true)
|
|
11
|
+
|
|
12
|
+
return [] unless response
|
|
13
|
+
|
|
14
|
+
response.dig(0, 'documents').map { Vantaca::Models::Document.new(it) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Download an actual file
|
|
18
|
+
# TODO: Add the zip=true parameter and unzip the file using Rubyzip
|
|
19
|
+
def document(community:, image_id:, &)
|
|
20
|
+
raise ArgumentError, 'Vantaca::Client#document requires a block' unless block_given?
|
|
21
|
+
|
|
22
|
+
download('/read/getDocument', assocCode: community, imgID: image_id, &)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
# Methods which allow creation, modification, and deletion of homeowner email addresses.
|
|
8
|
+
module Emails
|
|
9
|
+
# @param homeowner_id [Integer] The ID of the homeowner
|
|
10
|
+
# @param email_attrs [Hash] The email address details
|
|
11
|
+
# @option email_attrs [String] :email (required) The email address
|
|
12
|
+
# @option email_attrs [Boolean] :isPrimary Whether this is the primary email address
|
|
13
|
+
# @option email_attrs [String] :label Optional label for the email address (e.g., 'Work', 'Personal')
|
|
14
|
+
# @return [nil] The API response from the email creation endpoint
|
|
15
|
+
def create_email_address(homeowner_id, email_attrs)
|
|
16
|
+
post('/write/emailCreate', email_attrs.merge(hoid: homeowner_id))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param email_address_id [Integer] The ID of the email address to update
|
|
20
|
+
# @param email_attrs [Hash] The updated email address details
|
|
21
|
+
# @option email_attrs [String] :email (required) The email address
|
|
22
|
+
# @option email_attrs [Boolean] :isPrimary Whether this is the primary email address
|
|
23
|
+
# @option email_attrs [String] :label Optional label for the email address (e.g., 'Work', 'Personal')
|
|
24
|
+
# @return [nil] The API response from the email update endpoint
|
|
25
|
+
def update_email_address(email_address_id, email_attrs)
|
|
26
|
+
post('/write/emailUpdate', email_attrs.merge(emailID: email_address_id))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param email_address_id [Integer] The ID of the email address to delete
|
|
30
|
+
# @return [nil] The API response from the email deletion endpoint
|
|
31
|
+
def delete_email_address(email_address_id)
|
|
32
|
+
post('/write/emailDestroy', { emailID: email_address_id })
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) Valencia Management Group
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
|
|
6
|
+
module Vantaca
|
|
7
|
+
module Errors
|
|
8
|
+
# The base error class which more specific API error classes inherit from.
|
|
9
|
+
class ApiError < ::RuntimeError
|
|
10
|
+
DEFAULT_MESSAGE = 'An unknown error occurred.'
|
|
11
|
+
|
|
12
|
+
def initialize(response = nil)
|
|
13
|
+
@response = response
|
|
14
|
+
|
|
15
|
+
super()
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
return self.class::DEFAULT_MESSAGE unless @response
|
|
20
|
+
|
|
21
|
+
format(
|
|
22
|
+
'%<code>s: %<message>s (%<uri>s)',
|
|
23
|
+
code: @response.code,
|
|
24
|
+
# Vantaca doesn't put the error message in the response body - it's in the status header!
|
|
25
|
+
message: @response.response.message,
|
|
26
|
+
uri: filtered_uri
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def filtered_uri = @response.request.last_uri.to_s.gsub(/(company|login|pwd)=(?:[a-z0-9]+)/i, '\1=[FILTERED]')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The client submitted invalid information.
|
|
34
|
+
class ClientError < ApiError
|
|
35
|
+
DEFAULT_MESSAGE = 'An unknown client error occurred.'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# A request was made for a key/query that doesn't exist.
|
|
39
|
+
class NotFoundError < ClientError
|
|
40
|
+
DEFAULT_MESSAGE = 'The requested resource could not be found.'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Something happened but we don't know what and it's probably not our fault.
|
|
44
|
+
class InternalError < ApiError
|
|
45
|
+
DEFAULT_MESSAGE = 'An unknown internal error occurred.'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# The API took too long to respond, but everything might be fine later.
|
|
49
|
+
class TimeoutError < InternalError
|
|
50
|
+
DEFAULT_MESSAGE = 'The request timed out. Please try again in a moment.'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|