myjohndeere 0.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.
- checksums.yaml +7 -0
- data/.gitignore +52 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +37 -0
- data/LICENSE +21 -0
- data/README.md +109 -0
- data/Rakefile +8 -0
- data/lib/myjohndeere.rb +132 -0
- data/lib/myjohndeere/access_token.rb +79 -0
- data/lib/myjohndeere/api_support_item.rb +27 -0
- data/lib/myjohndeere/boundary.rb +18 -0
- data/lib/myjohndeere/core_ext/string.rb +9 -0
- data/lib/myjohndeere/errors.rb +10 -0
- data/lib/myjohndeere/field.rb +28 -0
- data/lib/myjohndeere/file_resource.rb +61 -0
- data/lib/myjohndeere/hash_utils.rb +33 -0
- data/lib/myjohndeere/json_attributes.rb +39 -0
- data/lib/myjohndeere/list_object.rb +94 -0
- data/lib/myjohndeere/map_layer.rb +41 -0
- data/lib/myjohndeere/map_layer_summary.rb +40 -0
- data/lib/myjohndeere/map_legend_item.rb +10 -0
- data/lib/myjohndeere/metadata_item.rb +8 -0
- data/lib/myjohndeere/organization.rb +16 -0
- data/lib/myjohndeere/organization_owned_resource.rb +17 -0
- data/lib/myjohndeere/requestable.rb +36 -0
- data/lib/myjohndeere/response.rb +31 -0
- data/lib/myjohndeere/rest_methods.rb +64 -0
- data/lib/myjohndeere/single_resource.rb +13 -0
- data/lib/myjohndeere/util.rb +54 -0
- data/lib/myjohndeere/version.rb +3 -0
- data/myjohndeere.gemspec +23 -0
- data/spec/fixtures.json +778 -0
- data/test/api_fixtures.rb +29 -0
- data/test/test_access_token.rb +60 -0
- data/test/test_boundary.rb +37 -0
- data/test/test_field.rb +47 -0
- data/test/test_file_resource.rb +48 -0
- data/test/test_helper.rb +36 -0
- data/test/test_list_object.rb +74 -0
- data/test/test_map_layer.rb +52 -0
- data/test/test_map_layer_summary.rb +52 -0
- data/test/test_myjohndeere.rb +56 -0
- data/test/test_organization.rb +42 -0
- data/test/test_requestable.rb +15 -0
- data/test/test_rest_methods.rb +34 -0
- data/test/test_util.rb +86 -0
- metadata +118 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class APISupportItem
|
3
|
+
include JSONAttributes
|
4
|
+
# see attributes_to_pull_from_json for the order if creating yourself
|
5
|
+
def initialize(args)
|
6
|
+
if args.length == 1 then
|
7
|
+
# assume the json object was passed
|
8
|
+
setup_attributes(args[0])
|
9
|
+
else
|
10
|
+
# otherwise assume normal construction according to the order for the json attributes
|
11
|
+
self.class.json_attributes.each_with_index do |attribute, i|
|
12
|
+
underscored = attribute.to_s.underscore
|
13
|
+
raise ArgumentError("You must pass #{attribute} as argument #{i+1}") if self.class.json_attributes.length <= i
|
14
|
+
self.send("#{underscored}=", args[i])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash()
|
20
|
+
ret_hash = {}
|
21
|
+
self.class.json_attributes.each do |attrib|
|
22
|
+
ret_hash[attrib] = self.send(attrib.to_s.underscore)
|
23
|
+
end
|
24
|
+
return ret_hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class Boundary < OrganizationOwnedResource
|
3
|
+
self.base_jd_resource = "boundaries"
|
4
|
+
self.list_resource_path = "organizations/%{organization_id}/fields/%{field_id}/#{self.base_jd_resource}"
|
5
|
+
self.retrieve_resource_path = "organizations/%{organization_id}/#{self.base_jd_resource}"
|
6
|
+
attributes_to_pull_from_json(:id, :name, :multipolygons, :active)
|
7
|
+
attr_accessor :field_id
|
8
|
+
|
9
|
+
def initialize(json_object, access_token = nil, field_id = nil)
|
10
|
+
super(json_object, access_token)
|
11
|
+
self.field_id = field_id
|
12
|
+
self.active = self.active.to_s.downcase == "true"
|
13
|
+
self.multipolygons = json_object["multipolygons"]
|
14
|
+
# This doesn't exist currently, not sure why
|
15
|
+
self.field_id ||= extract_link_with_rel_from_list("fields", /\/(\d+)\/(.+?)\/fields\Z/)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
# MyJohnDeereError is the base error from which all other more specific MyJohnError
|
3
|
+
# errors derive.
|
4
|
+
class MyJohnDeereError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
# Configuration error is raised when configuration hasn't been properly done
|
8
|
+
class ConfigurationError < MyJohnDeereError
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class Field < OrganizationOwnedResource
|
3
|
+
self.base_jd_resource = "fields"
|
4
|
+
self.list_resource_path = "organizations/%{organization_id}/#{self.base_jd_resource}"
|
5
|
+
self.retrieve_resource_path = "organizations/%{organization_id}/#{self.base_jd_resource}"
|
6
|
+
attributes_to_pull_from_json(:id, :name, :boundaries)
|
7
|
+
|
8
|
+
def initialize(json_object, access_token = nil)
|
9
|
+
super(json_object, access_token)
|
10
|
+
boundaries = json_object["boundaries"]
|
11
|
+
if boundaries && boundaries.length > 0 then
|
12
|
+
# If we embed, then we'll need to pass our id
|
13
|
+
self.boundary = Boundary.new(boundaries[0], access_token, self.id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def boundary
|
18
|
+
if @boundary.nil? then
|
19
|
+
@boundary = Boundary.retrieve(self.access_token, field_id: self.id, organization_id: self.organization_id)
|
20
|
+
end
|
21
|
+
return @boundary
|
22
|
+
end
|
23
|
+
|
24
|
+
def boundary=(val)
|
25
|
+
@boundary = val
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class FileResource < OrganizationOwnedResource
|
3
|
+
self.base_jd_resource = "fileResources"
|
4
|
+
self.list_resource_path = "mapLayers/%{map_layer_id}/#{self.base_jd_resource}"
|
5
|
+
self.retrieve_resource_path = self.base_jd_resource
|
6
|
+
attributes_to_pull_from_json(:id, :filename, :mimeType, :metadata, :timestamp)
|
7
|
+
|
8
|
+
def initialize(json_object, access_token = nil)
|
9
|
+
super(json_object, access_token)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create(access_token, organization_id, map_layer_id, file_type: nil,
|
13
|
+
metadata: [])
|
14
|
+
raise ArgumentError.new("You must pass a file_type") if file_type.nil?
|
15
|
+
|
16
|
+
case file_type
|
17
|
+
when :png
|
18
|
+
mime_type = 'image/png'
|
19
|
+
when :zip
|
20
|
+
mime_type = 'application/zip'
|
21
|
+
else
|
22
|
+
raise ArgumentError.new("You must specify either a zip or a png")
|
23
|
+
end
|
24
|
+
|
25
|
+
body = {
|
26
|
+
links: [
|
27
|
+
self.owning_organization_link_item(organization_id)
|
28
|
+
],
|
29
|
+
mimeType: mime_type,
|
30
|
+
metadata: metadata.map { |m| m.to_hash }
|
31
|
+
}
|
32
|
+
|
33
|
+
response = access_token.execute_request(:post,
|
34
|
+
build_resouce_base_path!(self.list_resource_path, {map_layer_id: map_layer_id}),
|
35
|
+
body: body
|
36
|
+
)
|
37
|
+
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc3", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayers/e2711205-c5df-445e-aad5-81eaf9090e6c", "X-Deere-Elapsed-Ms"=>"162", "Vary"=>"Accept-Encoding", "Expires"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
38
|
+
id = get_created_id_from_response_headers(self.base_jd_resource, response)
|
39
|
+
if id.nil? then
|
40
|
+
return nil
|
41
|
+
else
|
42
|
+
return self.new(HashUtils.deep_stringify_keys({"id" => id}.merge(body)))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.upload_file(access_token, file_resource_id, file_path)
|
47
|
+
File.open(file_path, "rb:UTF-8") do |f|
|
48
|
+
body = f.read()
|
49
|
+
response = access_token.execute_request(:put,
|
50
|
+
"#{self.base_jd_resource}/#{file_resource_id}",
|
51
|
+
body: body,
|
52
|
+
headers: {
|
53
|
+
'accept'=> 'application/vnd.deere.axiom.v3+json',
|
54
|
+
"Content-Type"=>'application/octet-stream' ,
|
55
|
+
"Content-Length" => body.bytesize.to_s
|
56
|
+
})
|
57
|
+
return response.code == 204
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class HashUtils
|
3
|
+
def self.transform_hash(original, options={}, &block)
|
4
|
+
original.inject({}){|result, (key,value)|
|
5
|
+
value = if (options[:deep] && Hash === value)
|
6
|
+
transform_hash(value, options, &block)
|
7
|
+
else
|
8
|
+
if Array === value
|
9
|
+
value.map{|v| transform_hash(v, options, &block)}
|
10
|
+
else
|
11
|
+
value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
block.call(result,key,value)
|
15
|
+
result
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Convert keys to strings
|
20
|
+
def self.stringify_keys(in_hash)
|
21
|
+
transform_hash(in_hash) {|hash, key, value|
|
22
|
+
hash[key.to_s] = value
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# Convert keys to strings, recursively
|
27
|
+
def self.deep_stringify_keys(in_hash)
|
28
|
+
transform_hash(in_hash, :deep => true) {|hash, key, value|
|
29
|
+
hash[key.to_s] = value
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
module JSONAttributes
|
3
|
+
module ClassMethods
|
4
|
+
attr_accessor :json_attributes
|
5
|
+
def attributes_to_pull_from_json(*attribs)
|
6
|
+
self.json_attributes = attribs
|
7
|
+
self.json_attributes.each do |attribute|
|
8
|
+
attribute = attribute.to_s.underscore
|
9
|
+
define_method("#{attribute}=") do |val|
|
10
|
+
instance_variable_set("@#{attribute}", val)
|
11
|
+
end
|
12
|
+
define_method(attribute) do
|
13
|
+
return instance_variable_get("@#{attribute}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def setup_attributes(json_data)
|
21
|
+
return if self.class.json_attributes.nil?
|
22
|
+
self.class.json_attributes.each do |attrib|
|
23
|
+
attrib = attrib.to_s
|
24
|
+
val = json_data[attrib]
|
25
|
+
if /(date)|(timestamp)/i.match(attrib) then
|
26
|
+
# try to parse it
|
27
|
+
val = Time.parse(val) rescue val
|
28
|
+
end
|
29
|
+
instance_variable_set("@#{attrib.underscore}", val)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.included(receiver)
|
35
|
+
receiver.extend ClassMethods
|
36
|
+
receiver.send :include, InstanceMethods
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class ListObject < Requestable
|
3
|
+
OPTION_ATTRIBUTES = [:count, :start, :etag]
|
4
|
+
attr_reader :data, :listable, :total, :options
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
OPTION_ATTRIBUTES.each do |attribute|
|
8
|
+
define_method("#{attribute}=") do |val|
|
9
|
+
options[attribute] = val
|
10
|
+
end
|
11
|
+
define_method(attribute) do
|
12
|
+
return options[attribute]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(listable, access_token, json_data,
|
17
|
+
options: {})
|
18
|
+
@options = options
|
19
|
+
# Confirm object is listable?
|
20
|
+
@listable = listable
|
21
|
+
@data = json_data["values"].collect { |i| listable.new(i, access_token) }
|
22
|
+
if self.using_etag?
|
23
|
+
MyJohnDeere.logger.info("Using etag, ignoring any specification about start/count")
|
24
|
+
self.start = 0
|
25
|
+
self.count = @data.length
|
26
|
+
else
|
27
|
+
MyJohnDeere.logger.info("Etag omitted using start/count")
|
28
|
+
self.start ||= 0
|
29
|
+
self.count ||= 10
|
30
|
+
end
|
31
|
+
# Total is the total record count as specified by the john deere response
|
32
|
+
@total = json_data["total"] || data.length
|
33
|
+
super(json_data, access_token)
|
34
|
+
end
|
35
|
+
|
36
|
+
def each(&blk)
|
37
|
+
self.data.each(&blk)
|
38
|
+
end
|
39
|
+
|
40
|
+
def next_page!()
|
41
|
+
return if !self.has_more?()
|
42
|
+
new_list = @listable.list(self.access_token,
|
43
|
+
count: self.count,
|
44
|
+
start: self.start + self.count,
|
45
|
+
etag: self.etag)
|
46
|
+
new_list.instance_variables.each do |iv|
|
47
|
+
self.instance_variable_set(iv, new_list.instance_variable_get(iv))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_more?()
|
52
|
+
return !self.using_etag? && self.start + self.data.length < self.total
|
53
|
+
end
|
54
|
+
|
55
|
+
def using_etag?
|
56
|
+
# will be equal "" or some other string
|
57
|
+
return !self.etag.nil?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# def iterate_through_john_deere_resource(john_deere_resource_path, options={})
|
62
|
+
# options = {
|
63
|
+
# headers: nil,
|
64
|
+
# body: ""
|
65
|
+
# }.merge(options)
|
66
|
+
# loop do
|
67
|
+
# response = self.request_against_access_token(:get, john_deere_resource_path, options)
|
68
|
+
|
69
|
+
# case response.code.to_s
|
70
|
+
# when "304" # Not modified, the headers won't change either
|
71
|
+
# logger.info("JohnDeere iteration not modified: #{john_deere_resource_path}")
|
72
|
+
# break
|
73
|
+
# when "200" # Success
|
74
|
+
# # now make the json and yield it to the block
|
75
|
+
# response_json = JSON.parse(response.body)
|
76
|
+
|
77
|
+
# yield(response_json, response.to_hash)
|
78
|
+
|
79
|
+
# # see if we have another page, will either be nil or the hash, which will have ["uri"]
|
80
|
+
# next_uri = response_json["links"].find { |link| link["rel"] == "nextPage" }
|
81
|
+
# full_resource_uri = next_uri.try(:[], "uri")
|
82
|
+
# break if full_resource_uri.nil?
|
83
|
+
|
84
|
+
# # convert it to a regular path so we don't have to mess with the
|
85
|
+
# # full route
|
86
|
+
# john_deere_resource_path = URI.parse(full_resource_uri).path
|
87
|
+
|
88
|
+
# # one final check
|
89
|
+
# break if john_deere_resource_path.nil?
|
90
|
+
# else
|
91
|
+
# break
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
# end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class MapLayer < OrganizationOwnedResource
|
3
|
+
self.base_jd_resource = "mapLayers"
|
4
|
+
self.list_resource_path = "mapLayerSummaries/%{map_layer_summary_id}/#{self.base_jd_resource}"
|
5
|
+
self.retrieve_resource_path = self.base_jd_resource
|
6
|
+
attributes_to_pull_from_json(:id, :title, :extent, :legends)
|
7
|
+
|
8
|
+
def initialize(json_object, access_token = nil)
|
9
|
+
super(json_object, access_token)
|
10
|
+
self.legends["ranges"].map! { |l| MapLegendItem.new(l) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.create(access_token, map_layer_summary_id, organization_id,
|
14
|
+
title: "", minimum_latitude: 0, maximum_latitude: 0,
|
15
|
+
minimum_longitude: 0, maximum_longitude:0, map_layer_id: "", map_legend_items: [])
|
16
|
+
body = {
|
17
|
+
links: [
|
18
|
+
self.owning_organization_link_item(organization_id)
|
19
|
+
],
|
20
|
+
title: "The title on the map layer",
|
21
|
+
extent: {
|
22
|
+
minimumLatitude: minimum_latitude,
|
23
|
+
maximumLatitude: maximum_latitude,
|
24
|
+
minimumLongitude: minimum_longitude,
|
25
|
+
maximumLongitude: maximum_longitude
|
26
|
+
},
|
27
|
+
legends: {
|
28
|
+
unitId: map_layer_id,
|
29
|
+
ranges: map_legend_items.map { |mls| mls.to_hash }
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
response = access_token.execute_request(:post,
|
34
|
+
build_resouce_base_path!(self.list_resource_path, {map_layer_summary_id: map_layer_summary_id}),
|
35
|
+
body: body
|
36
|
+
)
|
37
|
+
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc3", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayers/e2711205-c5df-445e-aad5-81eaf9090e6c", "X-Deere-Elapsed-Ms"=>"162", "Vary"=>"Accept-Encoding", "Expires"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Thu, 14 Sep 2017 15:52:24 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
38
|
+
return get_created_id_from_response_headers(self.base_jd_resource, response)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class MapLayerSummary < OrganizationOwnedResource
|
3
|
+
self.base_jd_resource = "mapLayerSummaries"
|
4
|
+
self.list_resource_path = "organizations/%{organization_id}/fields/%{field_id}/#{self.base_jd_resource}"
|
5
|
+
self.retrieve_resource_path = self.base_jd_resource
|
6
|
+
attributes_to_pull_from_json(:id, :title, :text, :metadata, :dateCreated, :lastModifiedDate)
|
7
|
+
|
8
|
+
def initialize(json_object, access_token = nil)
|
9
|
+
super(json_object, access_token)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create(access_token, organization_id, field_id,
|
13
|
+
title, caption, metadata = [], date_created=nil)
|
14
|
+
body = {
|
15
|
+
title: title,
|
16
|
+
text: caption,
|
17
|
+
links: [
|
18
|
+
owning_organization_link_item(organization_id),
|
19
|
+
{
|
20
|
+
rel: "contributionDefinition",
|
21
|
+
uri: "#{MyJohnDeere.configuration.endpoint}/#{MyJohnDeere.configuration.contribution_definition_id}"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
metadata: metadata.map { |md| md.to_hash },
|
25
|
+
dateCreated: (date_created || Time.now).strftime("%Y-%m-%dT%H:%M:%S.%LZ")
|
26
|
+
}
|
27
|
+
response = access_token.execute_request(:post,
|
28
|
+
build_resouce_base_path!(self.list_resource_path, {field_id: field_id, organization_id: organization_id}),
|
29
|
+
body: body
|
30
|
+
)
|
31
|
+
#{"Content-Type"=>"text/plain", "X-Deere-Handling-Server"=>"ldxtc4", "X-Frame-Options"=>"SAMEORIGIN", "Location"=>"https://sandboxapi.deere.com/platform/mapLayerSummaries/c5e9317e-eda6-48d3-acc8-c3bca3424858", "X-Deere-Elapsed-Ms"=>"362", "Vary"=>"Accept-Encoding", "Expires"=>"Wed, 13 Sep 2017 22:00:45 GMT", "Cache-Control"=>"max-age=0, no-cache", "Pragma"=>"no-cache", "Date"=>"Wed, 13 Sep 2017 22:00:45 GMT", "Transfer-Encoding"=>"chunked", "Connection"=>"close, Transfer-Encoding"}
|
32
|
+
id = get_created_id_from_response_headers(self.base_jd_resource, response)
|
33
|
+
if id.nil?
|
34
|
+
return nil
|
35
|
+
else
|
36
|
+
return self.new(HashUtils.deep_stringify_keys({"id" => id}.merge(body)))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class MapLegendItem < APISupportItem
|
3
|
+
attributes_to_pull_from_json(:label, :minimum, :maximum, :hexColor, :percent)
|
4
|
+
|
5
|
+
# see attributes_to_pull_from_json for the order if creating yourself
|
6
|
+
def initialize(*args)
|
7
|
+
super(args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module MyJohnDeere
|
2
|
+
class Organization < SingleResource
|
3
|
+
self.base_jd_resource = "organizations"
|
4
|
+
self.list_resource_path = self.base_jd_resource
|
5
|
+
self.retrieve_resource_path = self.base_jd_resource
|
6
|
+
attributes_to_pull_from_json(:id, :name, :type, :member)
|
7
|
+
|
8
|
+
def initialize(json_object, access_token = nil)
|
9
|
+
super(json_object, access_token)
|
10
|
+
end
|
11
|
+
|
12
|
+
def fields
|
13
|
+
return MyJohnDeere::Field.list(self.access_token, organization_id: self.id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|