dotloop_api 0.1.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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +34 -0
  6. data/.travis.yml +8 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +77 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +7 -0
  13. data/bin/setup +8 -0
  14. data/certs/shanedavies.pem +21 -0
  15. data/dotloop_api.gemspec +43 -0
  16. data/lib/dotloop_api/auth.rb +120 -0
  17. data/lib/dotloop_api/client.rb +89 -0
  18. data/lib/dotloop_api/end_points/account.rb +19 -0
  19. data/lib/dotloop_api/end_points/activity.rb +22 -0
  20. data/lib/dotloop_api/end_points/base.rb +37 -0
  21. data/lib/dotloop_api/end_points/batch.rb +34 -0
  22. data/lib/dotloop_api/end_points/contact.rb +9 -0
  23. data/lib/dotloop_api/end_points/detail.rb +28 -0
  24. data/lib/dotloop_api/end_points/document.rb +25 -0
  25. data/lib/dotloop_api/end_points/folder.rb +32 -0
  26. data/lib/dotloop_api/end_points/loop.rb +17 -0
  27. data/lib/dotloop_api/end_points/loop_template.rb +19 -0
  28. data/lib/dotloop_api/end_points/model_builder.rb +65 -0
  29. data/lib/dotloop_api/end_points/param_helper.rb +60 -0
  30. data/lib/dotloop_api/end_points/participant.rb +22 -0
  31. data/lib/dotloop_api/end_points/profile.rb +10 -0
  32. data/lib/dotloop_api/end_points/task.rb +23 -0
  33. data/lib/dotloop_api/end_points/task_list.rb +21 -0
  34. data/lib/dotloop_api/exceptions.rb +25 -0
  35. data/lib/dotloop_api/models/config.rb +18 -0
  36. data/lib/dotloop_api/models/contact.rb +38 -0
  37. data/lib/dotloop_api/models/profile/loop/activity.rb +13 -0
  38. data/lib/dotloop_api/models/profile/loop/detail.rb +129 -0
  39. data/lib/dotloop_api/models/profile/loop/folder/document.rb +27 -0
  40. data/lib/dotloop_api/models/profile/loop/folder.rb +25 -0
  41. data/lib/dotloop_api/models/profile/loop/participant.rb +9 -0
  42. data/lib/dotloop_api/models/profile/loop/tasklist/task.rb +16 -0
  43. data/lib/dotloop_api/models/profile/loop/tasklist.rb +22 -0
  44. data/lib/dotloop_api/models/profile/loop.rb +58 -0
  45. data/lib/dotloop_api/models/profile/loop_template.rb +16 -0
  46. data/lib/dotloop_api/models/profile.rb +63 -0
  47. data/lib/dotloop_api/version.rb +3 -0
  48. data/lib/dotloop_api.rb +47 -0
  49. data.tar.gz.sig +0 -0
  50. metadata +309 -0
  51. metadata.gz.sig +0 -0
@@ -0,0 +1,28 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Detail < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ attr_accessor :loop_id
6
+ undef_method :all
7
+ undef_method :create
8
+ undef_method :delete
9
+ def initialize(client:, profile_id: nil, loop_id: nil)
10
+ @profile_id = profile_id
11
+ @loop_id = loop_id
12
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop::Detail)
13
+ end
14
+
15
+ def find
16
+ build_model(@client.get(path)[:data])
17
+ end
18
+
19
+ def path
20
+ "/profile/#{@profile_id}/loop/#{@loop_id}/detail"
21
+ end
22
+
23
+ def build_model(attrs)
24
+ super(fix_hash(attrs))
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Document < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ attr_accessor :loop_id
6
+ attr_accessor :folder_id
7
+ undef_method :create
8
+ undef_method :delete
9
+ def initialize(client:, profile_id: nil, loop_id: nil, folder_id: nil)
10
+ @profile_id = profile_id
11
+ @loop_id = loop_id
12
+ @folder_id = folder_id
13
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop::Folder::Document)
14
+ end
15
+
16
+ def path
17
+ "/profile/#{@profile_id}/loop/#{@loop_id}/folder/#{@folder_id}/document"
18
+ end
19
+
20
+ def download(id:)
21
+ @client.download(single_path(id))
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Folder < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ attr_accessor :loop_id
6
+ undef_method :delete
7
+
8
+ def initialize(client:, profile_id: nil, loop_id: nil)
9
+ @profile_id = profile_id
10
+ @loop_id = loop_id
11
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop::Folder)
12
+ end
13
+
14
+ def all(options = {})
15
+ options_to_params(options)
16
+ @client.get(path, @params)[:data].map { |attrs| build_model(attrs) }
17
+ end
18
+
19
+ def path
20
+ "/profile/#{@profile_id}/loop/#{@loop_id}/folder"
21
+ end
22
+
23
+ private
24
+
25
+ def options_to_params(options)
26
+ @params = {
27
+ include_documents: options.key?(:include_documents) ? options[:include_documents] : true
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Loop < DotloopApi::EndPoints::Batch
4
+ attr_accessor :profile_id
5
+ undef_method :delete
6
+
7
+ def initialize(client:, profile_id: nil)
8
+ @profile_id = profile_id
9
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop)
10
+ end
11
+
12
+ def path
13
+ "/profile/#{@profile_id}/loop"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class LoopTemplate < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ undef_method :save
6
+ undef_method :create
7
+ undef_method :delete
8
+
9
+ def initialize(client:, profile_id: nil)
10
+ @profile_id = profile_id
11
+ super(client: client, path: path, type: DotloopApi::Models::Profile::LoopTemplate)
12
+ end
13
+
14
+ def path
15
+ "/profile/#{@profile_id}/loop-template"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,65 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ module ModelBuilder
4
+ def build_model(attrs)
5
+ model = @type.new(fix_nested_attributes(attrs))
6
+ model.client = @client if model.respond_to?(:client)
7
+ model.profile_id = @profile_id if model.respond_to?(:profile_id)
8
+ model.loop_id = @loop_id if model.respond_to?(:loop_id)
9
+ model.folder_id = @folder_id if model.respond_to?(:folder_id)
10
+ model
11
+ end
12
+
13
+ def build_documents(attrs)
14
+ attrs['documents'].map do |doc_attrs|
15
+ doc = DotloopApi::Models::Profile::Loop::Folder::Document.new(doc_attrs)
16
+ doc.client = @client
17
+ doc.profile_id = @profile_id
18
+ doc.loop_id = @loop_id
19
+ doc.folder_id = attrs['id']
20
+ doc
21
+ end
22
+ end
23
+
24
+ def build_details(attrs)
25
+ data = fix_hash(attrs)
26
+ data.keys.each_with_object({}) do |key, memo|
27
+ memo[key] = detail_model(key).new(data[key])
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def fix_nested_attributes(attrs)
34
+ attrs['details'] = build_details(attrs['details']) if attrs.key?('details')
35
+ attrs['documents'] = build_documents(attrs) if attrs.key?('documents')
36
+ attrs
37
+ end
38
+
39
+ def fix_hash(hash)
40
+ hash.each_with_object({}) do |(key, value), memo|
41
+ new_key = fix_key(key)
42
+ memo[new_key] = value.is_a?(Hash) ? fix_hash(value) : value
43
+ end
44
+ end
45
+
46
+ def fix_key(index)
47
+ index
48
+ .to_s
49
+ .delete("'")
50
+ .gsub('#', 'Number')
51
+ .gsub('%', 'Percent')
52
+ .gsub('$', 'Dollar')
53
+ .downcase
54
+ .gsub(/[^a-z]/, '_')
55
+ .squeeze('_')
56
+ .gsub(/^_*/, '')
57
+ .to_sym
58
+ end
59
+
60
+ def detail_model(key)
61
+ "DotloopApi::Models::Profile::Loop::Detail::#{key.to_s.camelize}".constantize
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,60 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class ParamHelper
4
+ include Virtus.model
5
+ attribute :batch_number, Integer, default: 1
6
+ attribute :batch_size, Integer, default: 100
7
+ attribute :filter
8
+ attribute :include_details, Boolean, default: false
9
+ attribute :sort_key
10
+ attribute :sort_direction, String, default: 'asc'
11
+
12
+ MAX_BATCH_SIZE = 100
13
+ FILTER_OPTIONS = %w[
14
+ updated_min created_min transaction_type transaction_status
15
+ ].freeze
16
+
17
+ def params
18
+ {
19
+ batch_number: @batch_number.to_i,
20
+ batch_size: size,
21
+ filter: filter_hash,
22
+ include_details: @include_details,
23
+ sort: sort
24
+ }.delete_if { |_, v| should_delete(v) }
25
+ end
26
+
27
+ private
28
+
29
+ def size
30
+ [@batch_size.to_i, MAX_BATCH_SIZE].min
31
+ end
32
+
33
+ def sort
34
+ return unless sort_key_valid?
35
+ "#{@sort_key}:#{direction}"
36
+ end
37
+
38
+ def direction
39
+ @sort_direction == 'asc' ? :asc : :desc
40
+ end
41
+
42
+ def sort_key_valid?
43
+ %w[
44
+ address closing_date created default expiration_date
45
+ listing_date purchase_price review_submission_date updated
46
+ ].include? @sort_key
47
+ end
48
+
49
+ def should_delete(value)
50
+ value.nil? ||
51
+ (value.is_a?(Integer) && value.zero?) ||
52
+ ((value.is_a?(String) || value.is_a?(Hash)) && value.empty?)
53
+ end
54
+
55
+ def filter_hash
56
+ (@filter.to_s.split('&').map { |var| var.split('=') }).to_h.slice(*FILTER_OPTIONS)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,22 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Participant < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ attr_accessor :loop_id
6
+
7
+ def initialize(client:, profile_id: nil, loop_id: nil)
8
+ @profile_id = profile_id
9
+ @loop_id = loop_id
10
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop::Participant)
11
+ end
12
+
13
+ def path
14
+ "/profile/#{@profile_id}/loop/#{@loop_id}/participant"
15
+ end
16
+
17
+ def build_model(attrs)
18
+ super(fix_hash(attrs))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Profile < DotloopApi::EndPoints::Base
4
+ undef_method :delete
5
+ def initialize(client:)
6
+ super(client: client, path: '/profile', type: DotloopApi::Models::Profile)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class Task < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ attr_accessor :loop_id
6
+ attr_accessor :task_list_id
7
+ undef_method :save
8
+ undef_method :create
9
+ undef_method :delete
10
+
11
+ def initialize(client:, profile_id: nil, loop_id: nil, task_list_id: nil)
12
+ @profile_id = profile_id
13
+ @loop_id = loop_id
14
+ @task_list_id = task_list_id
15
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop::TaskList::Task)
16
+ end
17
+
18
+ def path
19
+ "/profile/#{@profile_id}/loop/#{@loop_id}/tasklist/#{@task_list_id}/task"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module DotloopApi
2
+ module EndPoints
3
+ class TaskList < DotloopApi::EndPoints::Base
4
+ attr_accessor :profile_id
5
+ attr_accessor :loop_id
6
+ undef_method :save
7
+ undef_method :create
8
+ undef_method :delete
9
+
10
+ def initialize(client:, profile_id: nil, loop_id: nil)
11
+ @profile_id = profile_id
12
+ @loop_id = loop_id
13
+ super(client: client, path: path, type: DotloopApi::Models::Profile::Loop::TaskList)
14
+ end
15
+
16
+ def path
17
+ "/profile/#{@profile_id}/loop/#{@loop_id}/tasklist"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module DotloopApi
2
+ class BadRequest < StandardError; end
3
+ class Forbidden < StandardError; end
4
+ class MissingRefreshToken < StandardError; end
5
+ class MissingRevokeToken < StandardError; end
6
+ class NotFound < StandardError; end
7
+ class NotImplemented < StandardError; end
8
+ class TooManyRequests < StandardError; end
9
+ class Unauthorized < StandardError; end
10
+ class UnmatchState < StandardError; end
11
+ class UnprocessableEntity < StandardError; end
12
+ class CodeMap
13
+ def self.call(code)
14
+ return if code == 200
15
+ {
16
+ 400 => DotloopApi::BadRequest,
17
+ 401 => DotloopApi::Unauthorized,
18
+ 403 => DotloopApi::Forbidden,
19
+ 404 => DotloopApi::NotFound,
20
+ 422 => DotloopApi::UnprocessableEntity,
21
+ 429 => DotloopApi::TooManyRequests
22
+ }.fetch(code, StandardError)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Config
4
+ include Virtus.model
5
+ attribute :access_token
6
+ attribute :application, String, default: 'dotloop'
7
+ attribute :client_id, String, required: true
8
+ attribute :client_secret, String, required: true
9
+ attribute :expires_in
10
+ attribute :redirect_on_deny, Boolean, default: true
11
+ attribute :redirect_uri, String
12
+ attribute :refresh_token
13
+ attribute :scope, String
14
+ attribute :state, String
15
+ attribute :token_type, String
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Contact
4
+ ROLE_TYPES = %w[
5
+ ADMIN APPRAISER BUYER BUYER_ATTORNEY BUYING_AGENT BUYING_BROKER
6
+ ESCROW_TITLE_REP HOME_IMPROVEMENT_SPECIALIST HOME_INSPECTOR
7
+ HOME_SECURITY_PROVIDER HOME_WARRANTY_REP INSPECTOR INSURANCE_REP
8
+ LANDLORD LISTING_AGENT LISTING_BROKER LOAN_OFFICER LOAN_PROCESSOR
9
+ MANAGING_BROKER MOVING_STORAGE OTHER PROPERTY_MANAGER SELLER
10
+ SELLER_ATTORNEY TENANT TENANT_AGENT TRANSACTION_COORDINATOR
11
+ UTILITIES_PROVIDER
12
+ ].freeze
13
+ include Virtus.model
14
+ attribute :address
15
+ attribute :cell_phone
16
+ attribute :city
17
+ attribute :company_name
18
+ attribute :country
19
+ attribute :email
20
+ attribute :fax
21
+ attribute :first_name
22
+ attribute :home
23
+ attribute :id, Integer
24
+ attribute :last_name
25
+ attribute :license_number
26
+ attribute :office
27
+ attribute :phone
28
+ attribute :role
29
+ attribute :state
30
+ attribute :state_prov
31
+ attribute :street_name
32
+ attribute :street_number
33
+ attribute :updated, Time
34
+ attribute :zip_code
35
+ attribute :zip_postal_code
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Profile
4
+ class Loop
5
+ class Activity
6
+ include Virtus.model
7
+ attribute :date, Time
8
+ attribute :message
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,129 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Profile
4
+ class Loop
5
+ class Detail
6
+ include Virtus.model
7
+ attribute :contract_dates, DotloopApi::Models::Profile::Loop::Detail::ContractDates
8
+ attribute :contract_info, DotloopApi::Models::Profile::Loop::Detail::ContractInfo
9
+ attribute :financials, DotloopApi::Models::Profile::Loop::Detail::Financials
10
+ attribute :geographic_description, DotloopApi::Models::Profile::Loop::Detail::GeographicDescription
11
+ attribute :listing_information, DotloopApi::Models::Profile::Loop::Detail::ListingInformation
12
+ attribute :offer_dates, DotloopApi::Models::Profile::Loop::Detail::OfferDates
13
+ attribute :property_address, DotloopApi::Models::Profile::Loop::Detail::PropertyAddress
14
+ attribute :property, DotloopApi::Models::Profile::Loop::Detail::Property
15
+ attribute :referral, DotloopApi::Models::Profile::Loop::Detail::Referral
16
+ attr_accessor :client
17
+ attr_accessor :profile_id
18
+ attr_accessor :loop_id
19
+
20
+ def save
21
+ DotloopApi::EndPoints::Detail.new(
22
+ client: client, profile_id: profile_id, loop_id: loop_id
23
+ ).save(self)
24
+ end
25
+
26
+ class ContractDates
27
+ include Virtus.model
28
+ attribute :contract_agreement_date
29
+ attribute :closing_date
30
+ end
31
+
32
+ class ContractInfo
33
+ include Virtus.model
34
+ attribute :transaction_number
35
+ attribute :start_date
36
+ attribute :end_date
37
+ end
38
+
39
+ class Financials
40
+ include Virtus.model
41
+ attribute :earnest_money_amount
42
+ attribute :earnest_money_held_by
43
+ attribute :purchase_sale_price
44
+ attribute :sale_commission_rate
45
+ attribute :sale_commission_split_dollar_buy_side
46
+ attribute :sale_commission_split_dollar_sell_side
47
+ attribute :sale_commission_split_percent_buy_side
48
+ attribute :sale_commission_split_percent_sell_side
49
+ attribute :sale_commission_total
50
+ end
51
+
52
+ class GeographicDescription
53
+ include Virtus.model
54
+ attribute :addition
55
+ attribute :block
56
+ attribute :deed_book
57
+ attribute :deed_page
58
+ attribute :lot
59
+ attribute :map_grid
60
+ attribute :mls_area
61
+ attribute :legal_description
62
+ attribute :section
63
+ attribute :subdivision
64
+ end
65
+
66
+ class ListingInformation
67
+ include Virtus.model
68
+ attribute :current_price
69
+ attribute :description_of_other_liens
70
+ attribute :expiration_date
71
+ attribute :first_mortgage_balance
72
+ attribute :homeowner_association
73
+ attribute :homeowner_association_dues
74
+ attribute :listing_date
75
+ attribute :original_price
76
+ attribute :other_liens
77
+ attribute :property_excludes
78
+ attribute :property_includes
79
+ attribute :remarks
80
+ attribute :second_mortgage_balance
81
+ attribute :total_encumbrances
82
+ end
83
+
84
+ class Participant < DotloopApi::Models::Contact; end
85
+
86
+ class OfferDates
87
+ include Virtus.model
88
+ attribute :offer_date
89
+ attribute :inspection_date
90
+ attribute :occupancy_date
91
+ attribute :offer_expiration_date
92
+ end
93
+
94
+ class Property
95
+ include Virtus.model
96
+ attribute :bathrooms
97
+ attribute :bedrooms
98
+ attribute :lot_size
99
+ attribute :school_d
100
+ attribute :square_footage
101
+ attribute :type
102
+ attribute :year_built
103
+ end
104
+
105
+ class PropertyAddress
106
+ include Virtus.model
107
+ attribute :city
108
+ attribute :country
109
+ attribute :county
110
+ attribute :mls_number
111
+ attribute :parcel_tax_id
112
+ attribute :postal_code
113
+ attribute :property_address_country
114
+ attribute :state_or_province
115
+ attribute :street_name
116
+ attribute :street_number
117
+ attribute :unit_number
118
+ end
119
+
120
+ class Referral
121
+ include Virtus.model
122
+ attribute :referral_source
123
+ attribute :referral_percentage
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,27 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Profile
4
+ class Loop
5
+ class Folder
6
+ class Document
7
+ include Virtus.model
8
+ attribute :created, Time
9
+ attribute :id, Integer
10
+ attribute :name
11
+ attribute :updated, Time
12
+ attr_accessor :client
13
+ attr_accessor :profile_id
14
+ attr_accessor :loop_id
15
+ attr_accessor :folder_id
16
+
17
+ def download
18
+ DotloopApi::EndPoints::Document.new(
19
+ client: client, profile_id: profile_id, loop_id: loop_id, folder_id: folder_id
20
+ ).download(id: @id)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Profile
4
+ class Loop
5
+ class Folder
6
+ include Virtus.model
7
+ attribute :name
8
+ attribute :id, Integer
9
+ attribute :created, Time
10
+ attribute :updated, Time
11
+ attribute :documents, Array[DotloopApi::Models::Profile::Loop::Folder::Document]
12
+ attr_accessor :client
13
+ attr_accessor :profile_id
14
+ attr_accessor :loop_id
15
+
16
+ def document_list
17
+ @docuements = DotloopApi::EndPoints::Document.new(
18
+ client: client, profile_id: profile_id, loop_id: loop_id, folder_id: id
19
+ ).all
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ # module DotloopApi
2
+ # module Models
3
+ # class Profile
4
+ # class Loop
5
+ # class Participant; end
6
+ # end
7
+ # end
8
+ # end
9
+ # end
@@ -0,0 +1,16 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Profile
4
+ class Loop
5
+ class TaskList
6
+ class Task
7
+ include Virtus.model
8
+ attribute :due, Time
9
+ attribute :id, Integer
10
+ attribute :name
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ module DotloopApi
2
+ module Models
3
+ class Profile
4
+ class Loop
5
+ class TaskList
6
+ include Virtus.model
7
+ attribute :id, Integer
8
+ attribute :name
9
+ attr_accessor :client
10
+ attr_accessor :loop_id
11
+ attr_accessor :profile_id
12
+
13
+ def tasks
14
+ DotloopApi::EndPoints::Task.new(
15
+ client: client, profile_id: profile_id, loop_id: loop_id, task_list_id: id
16
+ ).all
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end