lusi_api 0.1.11

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: da1c5f2df15cb658a48d858532d3189d951e7141
4
+ data.tar.gz: 2e7dfb970b80eeb666c169f72fa563776f21683c
5
+ SHA512:
6
+ metadata.gz: cfbb149d9f00d6c8e1b7d8c4b6a0fafaaca45346ad007113a0ad795ab48215461959d26dcc2618ce940a6a6c277421cc4378ca539e1e86d514e312d065388e4f
7
+ data.tar.gz: 64a05269d80fe562a4eba9b51b917da2eb63697f0af0021a64b16d84eb42454756f0380e67c43dd72d7cf967233d1116a4213bdf2699bdd7bdfd8b5612ecce59
@@ -0,0 +1,58 @@
1
+ # IntelliJ files
2
+ .idea/
3
+ *.iml
4
+ *.iws
5
+
6
+ # Created by https://www.gitignore.io/api/ruby
7
+
8
+ ### Ruby ###
9
+ *.gem
10
+ *.rbc
11
+ /.config
12
+ /coverage/
13
+ /InstalledFiles
14
+ /pkg/
15
+ /spec/reports/
16
+ /spec/examples.txt
17
+ /test/tmp/
18
+ /test/version_tmp/
19
+ /tmp/
20
+
21
+ # Used by dotenv library to load environment variables.
22
+ .env
23
+
24
+ ## Specific to RubyMotion:
25
+ .dat*
26
+ .repl_history
27
+ build/
28
+ *.bridgesupport
29
+ build-iPhoneOS/
30
+ build-iPhoneSimulator/
31
+
32
+ ## Specific to RubyMotion (use of CocoaPods):
33
+ #
34
+ # We recommend against adding the Pods directory to your .gitignore. However
35
+ # you should judge for yourself, the pros and cons are mentioned at:
36
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
37
+ #
38
+ # vendor/Pods/
39
+
40
+ ## Documentation cache and generated files:
41
+ /.yardoc/
42
+ /_yardoc/
43
+ /doc/
44
+ /rdoc/
45
+
46
+ ## Environment normalization:
47
+ /.bundle/
48
+ /vendor/bundle
49
+ /lib/bundler/man/
50
+
51
+ # for a library or gem, you might want to ignore these files since the code is
52
+ # intended to run in multiple environments; otherwise, check them in:
53
+ Gemfile.lock
54
+ .ruby-version
55
+ .ruby-gemset
56
+
57
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
58
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lusi_api.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 lbaajh
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,235 @@
1
+ # LusiApi
2
+
3
+ A Ruby client for Lancaster University's LUSI API for student record management.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'lusi_api'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install lusi_api
20
+
21
+ ## Usage
22
+
23
+ ### Basic usage
24
+
25
+ Create an API instance with your LUSI account credentials:
26
+
27
+ ```ruby
28
+ require 'lusi_api'
29
+
30
+ api = LUSI::API::Core::API.new(api_user: 'Your LUSI username', api_password: 'Your LUSI password')
31
+ ```
32
+
33
+ Then pass this as the first argumnent of the ```get_instance``` factory methods of the API data classes.
34
+
35
+ ### Common classes
36
+
37
+ All LUSI API classes are subclasses of ```LUSI::API::Core::Object.```
38
+
39
+ Entities with identity are subclasses of ```LUSI::API::Core::ObjectWithID.``` Instances use the LUSI ID for equality and
40
+ hashing.
41
+
42
+ Properties consisting of an id/name pair are instances of ```LUSI::API::Core::Code.```
43
+
44
+ ### Lookup
45
+
46
+ The LUSI web API frequently provides codes to represent linked or embedded objects (for example, the department a
47
+ student is affiliated with). To assist with resolving codes to objects, the LUSI API provides the
48
+ ```LUSI::API::Core::Lookup``` module.
49
+
50
+ #### LookupTable
51
+
52
+ The ```LUSI::API::Core::Lookup::LookupTable``` class extends Ruby's ```Hash``` so that failed key lookups trigger an
53
+ attempt to read the value from an external data source by calling the ```get_value(key)``` method.
54
+
55
+ Subclasses implement ```get_value``` to perform the key lookup in the data source. If the lookup succeeds, the
56
+ corresponding value should be returned. If it fails, ```LUSI::API::Core::Lookup::LookupError``` should be raised.
57
+
58
+ If ```get_value``` returns a value, this value is added to the lookup table hash and returned as the result of the
59
+ lookup. If ```LookupError``` is raised, the usual ```Hash``` handling of a failed lookup is invoked (default value or
60
+ code block).
61
+
62
+ #### LUSILookupTable
63
+
64
+ The ```LUSI::API::Core::Lookup::LUSILookupTable``` class extends ```LookupTable``` to retrieve data from the LUSI web
65
+ API when a key lookup fails.
66
+
67
+ ```ruby
68
+ require 'lusi_api/core/lookup'
69
+
70
+ # The API class of the objects to be added to the lookup table
71
+ result_class = LUSI::API::Core::Code
72
+
73
+ # Positional arguments to the result class' get_instance method
74
+ args = ['arg1', 'arg2']
75
+
76
+ # Keyword arguments to the result class' get_instance method
77
+ kwargs = { arg1: 'value1', arg2: 'value2' }
78
+
79
+ # The parameter of the result_class' get_instance method used as the search condition
80
+ param = 'identity'
81
+
82
+ # The attribute of the result_class instance supplying the key value
83
+ # This may be a String or Symbol (the name of the attribute) or a Proc (accepting the result_class instance as its
84
+ # single argument and returning the key value). If not specified, the result_class instance is expected to have an
85
+ # attribute named 'identity' which supplies the key value.
86
+ # NameError is raised if the attribute lookup fails.
87
+ key_attribute = 'object_id'
88
+
89
+ begin
90
+ lookup = LUSI::API::Core::Lookup::LUSILookupTable(api, result_class, *args,
91
+ key_attribute: key_attribute,
92
+ param: param,
93
+ **kwargs)
94
+ rescue NameError
95
+ # The key attribute lookup failed
96
+ end
97
+ ```
98
+
99
+ Some lookup tables (for example, academic weeks, countries) can be populated from a single call to the LUSI web API.
100
+ ```LUSILookupTable``` provides the ```load``` method to support this.
101
+
102
+ A lookup table which supports bulk loading should include the constructor parameter ```loadable: true``` and may
103
+ specify an optional hash of default parameter values for the ```load``` method:
104
+
105
+ ```ruby
106
+ begin
107
+ lookup = LUSI::API::Core::Lookup::LUSILookupTable(api, result_class, ...,
108
+ loadable: true,
109
+ load_params: {})
110
+ end
111
+ ```
112
+
113
+
114
+ ### Exceptions
115
+
116
+ All exceptions thrown by the LUSI API are subclasses of ```LUSI::API::Core::APIError.```
117
+
118
+ The exception hiearchy is:
119
+ ```
120
+ APIError
121
+ APICallError
122
+ APITimeoutError
123
+ APIResponseError
124
+ APIContentError
125
+ APIPermissionError
126
+ ```
127
+
128
+ Methods which interact with the LUSI web API, such as the ```get_instance``` method of the data classes, should
129
+ rescue at least ```LUSI::API::Core::APIError``` to handle network problems.
130
+
131
+ ```ruby
132
+ begin
133
+ result = SomeClass.get_instance(api)
134
+ rescue LUSI::API::Core::APITimeoutError
135
+ # Subclass of APICallError
136
+ # Raised when the LUSI API does not respond within the timeout period
137
+ rescue LUSI::API::Core::APICallError
138
+ # Subclass of APIError
139
+ # Raised when there is a general problem with the LUSI API call (e.g. network error)
140
+ rescue LUSI::API::Core::APIContentError
141
+ # Subclass of APIResponseError
142
+ # Raised when there is a problem parsing the XML response from the LUSI API
143
+ rescue LUSI::API::Core::APIPermissionError
144
+ # Subclass of APIResponseError
145
+ # Raised when the LUSI account does not have permission to call the requested API method
146
+ rescue LUSI::API::Core::APIError
147
+ # Raised when any other problem occurs
148
+ end
149
+ ```
150
+
151
+ ### Calendar module
152
+
153
+ The ```LUSI::API::Calendar``` module provides the classes ```Week``` and ```Year``` to represent LUSI academic week and
154
+ year objects. Both classes extend ```LUSI::API::Core::Code.```
155
+
156
+ #### Year
157
+
158
+ Years in LUSI are objects with an 6-digit zero-padded identity code derived from the year: 000nnn
159
+ where nnn = year - 1900.
160
+
161
+ e.g. 2016 = 2016 - 1900 = 000116
162
+
163
+ ```ruby
164
+ require 'lusi_api/calendar'
165
+
166
+ # Get an array of all years in LUSI
167
+ all_years = LUSI::API::Calendar::Year.get_instance(api, lookup)
168
+ year_2016 = all_years.select { |year| year.identity == '000116' }
169
+
170
+ # Year properties
171
+ puts <<EOF
172
+ Identity: #{year_2016.identity}
173
+ Description: #{year_2016.description}
174
+ Full year description: #{year_2016.full_year}
175
+ EOF
176
+ ```
177
+
178
+ #### Week
179
+
180
+ ```ruby
181
+ require 'lusi_api/calendar'
182
+
183
+ # Get an array of all weeks in LUSI
184
+ all_weeks = LUSI::API::Calendar::Week.get_instance(api, lookup)
185
+
186
+ # Get an array of all weeks for a specific year
187
+ # year may be a year identity string or a LUSI::API::Calendar::Year instance
188
+ year_weeks = LUSI::API::Calendar::Week.get_instance(api, lookup, year_identity: '000116')
189
+
190
+ # Get the current academic week
191
+ current_week = LUSI::API::Calendar::Week.current_academic_week(api)
192
+
193
+ # Week properties
194
+ # - monday_date is an instance of DateTime
195
+ # - year is an instance of LUSI::API::Calendar::Year
196
+ puts <<EOF
197
+ Identity: #{current_week.identity}
198
+ Description: #{current_week.description}
199
+ Academic timetable week ID: #{current_week.att_identity}
200
+ Monday date: #{current_week.monday_date}
201
+ Term: #{current_week.term}
202
+ Year: #{current_week.year}
203
+ EOF
204
+ ```
205
+
206
+
207
+ ### Country module
208
+
209
+ ### Course module
210
+
211
+ ### Enrolment module
212
+
213
+ ### Organisation module
214
+
215
+ ### Person module
216
+
217
+ ### Service account module
218
+
219
+ ### Service method module
220
+
221
+ ## Development
222
+
223
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
224
+
225
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
226
+
227
+ ## Contributing
228
+
229
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lusi_api.
230
+
231
+
232
+ ## License
233
+
234
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
235
+
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
3
+
4
+ # YARD::Rake::YardocTask.new do |t|
5
+ # t.files = ['lib/**/*.rb'] # optional
6
+ # t.options = ['--any', '--extra', '--opts', '--private', '--protected'] # optional
7
+ # t.stats_options = ['--list-undoc'] # optional
8
+ # end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "lusi_api"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ module LUSI
2
+ module API
3
+
4
+ end
5
+ end
@@ -0,0 +1,234 @@
1
+ require 'lusi_api/core/code'
2
+ require 'lusi_api/core/util'
3
+ require 'lusi_api/core/xml'
4
+
5
+
6
+ module LUSI
7
+ module API
8
+ module Calendar
9
+
10
+
11
+ # Represents an academic week in the LUSI API
12
+ class Week < LUSI::API::Core::Code
13
+
14
+ # @!attribute [rw] att_identity
15
+ # @return [Integer, nil] the academic timetable (ATT) week identity
16
+ attr_accessor :att_identity
17
+
18
+ # @!attribute [rw] monday_date
19
+ # @return [DateTime, nil] the Monday starting the week
20
+ attr_accessor :monday_date
21
+
22
+ # @!attribute [rw] term
23
+ # @return [String, nil] The term/period the week is in
24
+ attr_accessor :term
25
+
26
+ # @!attribute [rw] year
27
+ # @return [LUSI::API::Calendar::Year, nil] the academic year containing the week
28
+ attr_accessor :year
29
+
30
+ # Returns a Week instance for the current academic week
31
+ # @param api [LUSI::API::Core::API] the LUSI API instance
32
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
33
+ # @return [LUSI::API::Calendar::Week] the current academic week
34
+ # @yield [obj] Passes the Week instance to the block
35
+ # @yieldparam obj [LUSI::API::Calendar::Week] the Week instance
36
+ def self.get_current_academic_week(api = nil, lookup = nil)
37
+ xml = api.call('LUSIReference', 'General.asmx', 'GetCurrentAcademicWeek')
38
+ obj = new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Week'), lookup)
39
+ yield(obj) if block_given?
40
+ obj
41
+ end
42
+
43
+ # Returns Week instances for all or one specific academic year
44
+ # @param api [LUSI::API::Core::API] the LUSI API instance
45
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
46
+ # @param use_lookup [Boolean] if true, use the lookup service to identify instances before trying the API
47
+ # @param year [LUSI::API::Calendar::Year, String, nil] the academic year required (all defined weeks if nil)
48
+ # @return [Array<LUSI::API::Calendar::Week>] the selected acadmic weeks
49
+ # @yield [obj] Passes the Week instance to the block
50
+ # @yieldparam obj [LUSI::API::Calendar::Week] the Week instance
51
+ def self.get_instance(api = nil, lookup = nil, use_lookup: true, year_identity: nil)
52
+ # Search the lookup service
53
+ if lookup and use_lookup
54
+ week = lookup.lookup(:week, year_identity)
55
+ if week
56
+ yield(week) if block_given?
57
+ return week
58
+ end
59
+ end
60
+ # Search the API
61
+ super(api, lookup, 'LUSIReference', 'General.asmx', 'GetWeeks', 'xmlns:Week', year_identity: year_identity)
62
+ end
63
+
64
+ # Initialises a new Week instance
65
+ # @param (see LUSI::API::Core::Code#initialize)
66
+ # @param att_identity [Integer, nil] the default academic timetable (ATT) identity
67
+ # @param monday_date [DateTime, nil] the default Monday week-start date
68
+ # @param term [String, nil] the default term
69
+ # @param year [LUSI::API::Calendar::Year, nil] the default academic year
70
+ # @return [void]
71
+ def initialize(xml = nil, lookup = nil, term: nil, monday_date: nil, year: nil, att_identity: nil, **kwargs)
72
+ super(xml, lookup, **kwargs)
73
+ @att_identity = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:ATTIdentity', att_identity)
74
+ @monday_date = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:MondayDate', monday_date)
75
+ @term = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Term', term)
76
+ @year = LUSI::API::Core::XML.lookup(xml, lookup, :year, 'xmlns:Year/xmlns:Identity', year)
77
+ end
78
+
79
+ protected
80
+
81
+ def self.get_instance_params(**kwargs)
82
+ year = kwargs[:year_identity] || ''
83
+ year = year.identity if year.is_a?(Year)
84
+ params = super(**kwargs)
85
+ params[:YearIdentity] = year || ''
86
+ params
87
+ end
88
+
89
+ end
90
+
91
+
92
+ # Represents an academic year in the LUSI API
93
+ class Year < LUSI::API::Core::Code
94
+
95
+ extend LUSI::API::Core::Util
96
+
97
+ # @!attribute [rw] full_year
98
+ # @return [String, nil] the full text description of the academic year
99
+ attr_accessor :full_year
100
+
101
+ # @!attribute [rw] lookup
102
+ # @return [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
103
+ attr_accessor :lookup
104
+
105
+ # Returns a Year instance for the current academic year
106
+ # @param api [LUSI::API::Core::API] the LUSI API instance
107
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
108
+ # @return [LUSI::API::Calendar::Year] the current academic year
109
+ # @yield [obj] Passes the Year instance to the block
110
+ # @yieldparam obj [LUSI::API::Calendar::Year] the Year instance
111
+ def self.get_current_academic_year(api = nil, lookup = nil)
112
+ xml = api.call('LUSIReference', 'General.asmx', 'GetCurrentAcademicYear')
113
+ obj = new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Year'), lookup)
114
+ yield(obj) if block_given?
115
+ obj
116
+ end
117
+
118
+ # Returns selected or all defined year instances
119
+ # @param api [LUSI::API::Core::API] the LUSI API instance
120
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
121
+ # Remaining positional parameters are years or year identities of the required years
122
+ # @param use_lookup [Boolean] if true, use the lookup service to identify instances before trying the API
123
+ # @return [Array<LUSI::API::Calendar::Year>, nil] the defined year instances
124
+ # @yield [obj] Passes the Year instance to the block
125
+ # @yieldparam obj [LUSI::API::Calendar::Year] the Year instance
126
+ def self.get_instance(api = nil, lookup = nil, *years, use_lookup: true, **kwargs)
127
+ results = nil
128
+ # Search the lookup service if required
129
+ if lookup && use_lookup
130
+ year_lookup = lookup.service(:year)
131
+ results = year_lookup.values if year_lookup
132
+ end
133
+ # Search the API if required
134
+ results = super(api, lookup, 'LUSIReference', 'General.asmx', 'GetYears', 'xmlns:Year') if results.nil?
135
+ # Return the results
136
+ if results.nil? || years.nil? || years.empty?
137
+ # No results or no filtering required
138
+ results
139
+ else
140
+ # Return the year instances for the specified years
141
+ years = years.map { |year| lusi_year_identity(year) }
142
+ results.select { |result| years.include?(result.identity) }
143
+ end
144
+ end
145
+
146
+ # Initialises a new Year instance
147
+ # @param (see LUSI::API::Core::Code#initialize)
148
+ # @param full_year [String, nil] the full text description of the academic year
149
+ # @return [void]
150
+ def initialize(xml = nil, lookup = nil, full_year: nil, **kwargs)
151
+ super(xml, lookup, **kwargs)
152
+ self.full_year = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:FullYear', full_year)
153
+ # Store the lookup service for year arithmetic operations
154
+ self.lookup = lookup
155
+ end
156
+
157
+ # Returns the year instance n years after this one
158
+ # @param years [Integer] the number of years to add to the instance's year
159
+ # @return [LUSI::API::Calendar::Year] the year instance
160
+ def +(years = 0)
161
+ self.offset(years)
162
+ end
163
+
164
+ # Returns the year instance n years before this one
165
+ # @param years [Integer] the number of years to subtract from the instance's year
166
+ # @return [LUSI::API::Calendar::Year] the year instance
167
+ def -(years = 0)
168
+ self.offset(-years)
169
+ end
170
+
171
+ # Returns the year instance immediately following this one
172
+ # @return [LUSI::API::Calendar::Year] the year instance
173
+ def next(count = 1)
174
+ count = count.to_i
175
+ if count == 1
176
+ self.offset(1)
177
+ else
178
+ result = []
179
+ (1..count).each { |offset| result.push(self.offset(offset)) }
180
+ result
181
+ end
182
+ end
183
+
184
+ # Returns the year instance n years after/before this one
185
+ # @param years [Integer] the number of years to add to the instance's year
186
+ # @return [LUSI::API::Calendar::Year] the year instance
187
+ def offset(years = 0)
188
+ return self if years == 0
189
+ year = self.class.lusi_year(self, self.lookup, as_instance: true, offset: years)
190
+ end
191
+
192
+ # Returns the year instance immediately preceding this one
193
+ # @return [LUSI::API::Calendar::Year] the year instance
194
+ def previous(count = 1)
195
+ count = count.to_i
196
+ if count == 1
197
+ self.offset(-1)
198
+ else
199
+ result = []
200
+ (1..count).each { |offset| result.push(self.offset(-offset)) }
201
+ result
202
+ end
203
+ end
204
+
205
+ # Returns a list of year instances around (immediately preceding and following) this one
206
+ # @param from [Integer, Range] the starting offset relative to the current year
207
+ # @param to [Integer] the ending offset relative to the current year
208
+ # @return [Array<LUSI::API::Calendar::Year>] the year instances
209
+ def range(from = nil, to = nil)
210
+ from = (from..to) unless from.is_a?(Range)
211
+ result = []
212
+ from.each { |offset| result.push(self.offset(offset)) }
213
+ result
214
+ end
215
+
216
+ # Returns a string representation of the Year instance
217
+ # @return [String] the string representation of the Year instance
218
+ def to_s
219
+ self.full_year
220
+ end
221
+
222
+ protected
223
+
224
+ # Returns an empty parameter hash for the LUSI API call
225
+ def self.get_instance_params(**kwargs)
226
+ {}
227
+ end
228
+
229
+ end
230
+
231
+
232
+ end
233
+ end
234
+ end