lusi_api 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ require 'date'
2
+
3
+
4
+ module LUSI
5
+ module API
6
+ module Core
7
+ module Util
8
+
9
+
10
+ # Converts a LUSI year identity code into a numeric or LUSI::API::Calendar::Year instance representing the year
11
+ # If a lookup service is supplied, the identity code is resolved by a LUSI API call.
12
+ # Otherwise, the year is calculated as: year = year_identity.to_i + 1900
13
+ # @param year_identity [String] the year identity code
14
+ # @param lookup [LUSI::API::Lookup::LookupService] the LUSI lookup service
15
+ # @param as_instance [Boolean] if true, return a LUSI::API::Calendar::Year instance instead of a year
16
+ # @param offset [Integer] an offset (in years) to apply to the year
17
+ # @return [Integer] the year represented by the year identity code
18
+ def lusi_year(year_identity = nil, lookup = nil, as_instance: false, offset: 0)
19
+
20
+ # Convert the year identity to an integer
21
+ case
22
+ when year_identity.is_a?(LUSI::API::Calendar::Week)
23
+ year_identity = year_identity.year.identity.to_i
24
+ when year_identity.is_a?(LUSI::API::Calendar::Year)
25
+ year_identity = year_identity.identity.to_i
26
+ when year_identity.is_a?(String) && year_identity.length == 6
27
+ # Assume a 6-character string is an identity code
28
+ year_identity = year_identity.to_i
29
+ else
30
+ # Assume anything else is a year and convert it to an identity
31
+ year_identity = lusi_year_identity(year.to_i)
32
+ end
33
+
34
+ # Apply the offset
35
+ year_identity += offset.to_i
36
+
37
+ year_identity = "%06d" % year_identity
38
+ if lookup
39
+ year = lookup.lookup(:year, year_identity)
40
+ if as_instance
41
+ year
42
+ else
43
+ year ? year.full_year.to_i : nil
44
+ end
45
+ else
46
+ # Year identities are (year - 1900) zero-padded to six digits
47
+ year = year_identity.to_i + 1900
48
+ if as_instance
49
+ yy = year % 100
50
+ description = "%02s/%02s" % [yy, (yy + 1) % 100]
51
+ LUSI::API::Calendar::Year.new(nil, lookup, code: year_identity, description: description,
52
+ full_year: year.to_s)
53
+ else
54
+ year
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ # Converts a year into a LUSI year identity code
61
+ # @param year [Date, DateTime, Numeric, String, LUSI::API::Calendar::Week, LUSI::API::Calendar::Year] the year
62
+ # @param offset [Integer] an offset (in years) to apply to the year
63
+ # @return [String] the year identity code
64
+ def lusi_year_identity(year = nil, offset: 0)
65
+
66
+ offset = offset.to_i
67
+
68
+ # Get the year as an integer
69
+ # If the year is provided as an identity, it's converted to a numeric year
70
+ year_identity = nil
71
+ case
72
+ when year.is_a?(LUSI::API::Calendar::Week)
73
+ year_identity = year.year.identity
74
+ when year.is_a?(LUSI::API::Calendar::Year)
75
+ year_identity = year.identity
76
+ when year.is_a?(Date) || year.is_a?(DateTime) || year.is_a?(Time)
77
+ year = year.year
78
+ when year.is_a?(String)
79
+ if year.length == 6
80
+ year_identity = year
81
+ else
82
+ year = year.to_i
83
+ end
84
+ when year.is_a?(Numeric)
85
+ year = year.to_i
86
+ else
87
+ year = Time.now.year
88
+ end
89
+ year = year_identity.to_i + 1900 if year_identity
90
+
91
+ # Return the year identity for the year with offset applied
92
+ "%06d" % (year + offset - 1900)
93
+
94
+ end
95
+
96
+ # Creates a LUSI Year instance from a year
97
+ #
98
+
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,168 @@
1
+ require 'date'
2
+ require 'nokogiri'
3
+
4
+
5
+ module LUSI
6
+ module API
7
+ module Core
8
+ module XML
9
+
10
+ NAMESPACE = 'Uol.Cis.Lusi.WebService'
11
+
12
+ def self.lookup(xml = nil, lookup = nil, service = nil, path = nil, default = nil, &block)
13
+ return default if xml.nil? || lookup.nil? || service.nil?
14
+ key = xml_content_at(xml, path)
15
+ result = lookup.lookup(service, key, default)
16
+ yield(result) if block_given?
17
+ result
18
+ end
19
+
20
+ def self.xml(xml = nil, path = nil, default = nil, filter: nil, &block)
21
+ _xml(xml, path, default, single: false, content: false, filter: filter, &block)
22
+ end
23
+
24
+ def self.xml_at(xml = nil, path = nil, default = nil, &block)
25
+ _xml(xml, path, default, single: true, content: false, &block)
26
+ end
27
+
28
+ def self.xml_boolean(xml = nil, path = nil, default = nil, &block)
29
+ content = xml_content(xml, path, default)
30
+ content.map { |str| xml_boolean_parse(str, default) }
31
+ end
32
+
33
+ def self.xml_boolean_at(xml = nil, path = nil, default = nil, &block)
34
+ xml_boolean_parse(xml_content_at(xml, path, default), default)
35
+ end
36
+
37
+ def self.xml_boolean_parse(boolstr = nil, default = nil, true_values = nil, false_values = nil, &block)
38
+ boolstr = boolstr.to_s.downcase
39
+ false_values ||= ['false', 'n', 'no']
40
+ true_values ||= ['true', 'y', 'yes']
41
+ if true_values.include?(boolstr)
42
+ true
43
+ elsif false_values.include?(boolstr)
44
+ false
45
+ else
46
+ default
47
+ end
48
+ end
49
+
50
+ def self.xml_content(xml = nil, path = nil, default = nil, &block)
51
+ _xml(xml, path, default, single: false, content: true, &block)
52
+ end
53
+
54
+ def self.xml_content_at(xml = nil, path = nil, default = nil, &block)
55
+ _xml(xml, path, default, single: true, content: true, &block)
56
+ end
57
+
58
+ def self.xml_datetime(xml = nil, path = nil, default = nil, format = nil, &block)
59
+ content = xml_content(xml, path, default)
60
+ content.map { |str| xml_datetime_parse(str, default, format) }
61
+ end
62
+
63
+ def self.xml_datetime_at(xml = nil, path = nil, default = nil, format = nil, &block)
64
+ xml_datetime_parse(xml_content_at(xml, path, default), default, format)
65
+ end
66
+
67
+ def self.xml_datetime_parse(datestr = nil, default = nil, format = nil, &block)
68
+ return default if datestr.nil?
69
+ format ||= '%Y-%m-%dT%H:%M:%S'
70
+ begin
71
+ DateTime.strptime(datestr, format)
72
+ rescue Exception
73
+ default
74
+ end
75
+ end
76
+
77
+ def self.xml_float(xml = nil, path = nil, default = nil, &block)
78
+ content = xml_content(xml, path, default)
79
+ content.map { |str| xml_float_parse(str, default) }
80
+ end
81
+
82
+ def self.xml_float_at(xml = nil, path = nil, default = nil, &block)
83
+ xml_float_parse(xml_content_at(xml, path, default), default)
84
+ end
85
+
86
+ def self.xml_float_parse(floatstr, default = nil)
87
+ begin
88
+ floatstr.to_f
89
+ rescue
90
+ default
91
+ end
92
+ end
93
+
94
+ def self.xml_int(xml = nil, path = nil, default = nil, &block)
95
+ content = xml_content(xml, path, default)
96
+ content.map { |str| xml_int_parse(str, default) }
97
+ end
98
+
99
+ def self.xml_int_at(xml = nil, path = nil, default = nil, &block)
100
+ xml_int_parse(xml_content_at(xml, path, default), default)
101
+ end
102
+
103
+ def self.xml_int_parse(intstr, default = nil)
104
+ begin
105
+ intstr.to_i
106
+ rescue
107
+ default
108
+ end
109
+ end
110
+
111
+ protected
112
+
113
+ def self._xml(xml = nil, path = nil, default = nil, single: false, content: true, filter: nil, &block)
114
+
115
+ # Return the default value if no XML is given
116
+ return default if xml.nil?
117
+
118
+ # Return the XML value itself if it's not an accepted XML instance
119
+ return xml unless xml.is_a?(Nokogiri::XML::Node) or xml.is_a?(Nokogiri::XML::NodeSet)
120
+
121
+ if single
122
+ # Return the first matching node
123
+ result = xml.at_xpath(path)
124
+ if result.nil?
125
+ default
126
+ else
127
+ content ? result.content.to_s : result
128
+ end
129
+ else
130
+ # If a code block is provided, return an array of results of applying the block to each node, or an empty
131
+ # array if no matches exist.
132
+ # Otherwise return the matching nodeset, or nil of no matches exist
133
+ nodeset = xml.xpath(path)
134
+ if block
135
+ if nodeset.nil? then
136
+ # Return an empty array for an empty nodeset
137
+ []
138
+ elsif filter.nil?
139
+ # Apply the block to every node
140
+ if content
141
+ nodeset.to_a.map { |node| block.call(node.content.to_s) }
142
+ else
143
+ nodeset.to_a.map(&block)
144
+ end
145
+ else
146
+ # Apply the block only to nodes for which the filter returns true
147
+ result = []
148
+ if content
149
+ nodeset.each { |node| result.push(node.content.to_s) if filter.call(node) }
150
+ else
151
+ nodeset.each { |node| result.push(block.call(node)) if filter.call(node) }
152
+ end
153
+ result
154
+ end
155
+ else
156
+ if content
157
+ nodeset.to_a.map { |node| node.content.to_s }
158
+ else
159
+ nodeset
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,111 @@
1
+ require 'lusi_api/core/code'
2
+ require 'lusi_api/core/xml'
3
+
4
+
5
+ module LUSI
6
+ module API
7
+ module Country
8
+
9
+ # Represents a country in the LUSI API
10
+ class Country < LUSI::API::Core::Code
11
+
12
+ # @!attribute [rw] iso_alpha2_code
13
+ # @return [String, nil] the ISO alpha-2 code for the country
14
+ attr_accessor :iso_alpha2_code
15
+
16
+ # Initialises a new Country instance
17
+ # @param (see LUSI::API::Core::Code#initialize)
18
+ # @param iso_alpha2_code [String, nil] the default ISO alpha-2 code for the country
19
+ # @return [void]
20
+ def initialize(xml = nil, lookup = nil, iso_alpha2_code: nil, **kwargs)
21
+ super(xml, lookup, **kwargs)
22
+ @iso_alpha2_code = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:ISOAlpha2Code', iso_alpha2_code)
23
+ end
24
+
25
+ # Returns a string representation of the Country instance
26
+ # @return [String] the string representation of the Country instance
27
+ def to_s
28
+ @description
29
+ end
30
+
31
+ end
32
+
33
+
34
+ # Represents the country component of an address in the LUSI API
35
+ class AddressCountry < Country
36
+
37
+ # @!attribute [rw] region
38
+ # @return [String. nil] the text description of the region of the address
39
+ attr_accessor :region
40
+
41
+ # Returns AddressCountry instances matching the supplied parameters
42
+ # @param (see LUSI::API::Country::Country#get_instance)
43
+ # @param iso_alpha2_code [String, nil] the ISO alpha-2 code to search for
44
+ # @param region [String, nil] the region to search for
45
+ # @return [Array<AddressCountry>, nil] the matching AddressCountry instances
46
+ # @yield [obj] Passes the AddressCountry instance to the block
47
+ # @yieldparam obj [LUSI::API::Country::AddressCountry] the AddressCountry instance
48
+ def self.get_instance(api = nil, lookup = nil, iso_alpha2_code: nil, region: nil, **kwargs)
49
+ super(api, lookup, 'LUSIReference', 'Lookup.asmx', 'GetAddressCountries', 'xmlns:AddressCountry',
50
+ iso_alpha2_code: iso_alpha2_code, region: region, **kwargs)
51
+ end
52
+
53
+ # Initialises a new AddressCountry instance
54
+ # @param (see Country#initialize)
55
+ # @param region [String, nil] the default region
56
+ # @return [void]
57
+ def initialize(xml = nil, lookup = nil, region: nil, **kwargs)
58
+ super(xml, lookup, **kwargs)
59
+ @region = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Region', region)
60
+ end
61
+
62
+ protected
63
+
64
+ # Returns a parameter hash for the LUSI API call
65
+ # @params (see #get_instance)
66
+ # @return [Hash<String, any] the parameter hash for the LUSI API call
67
+ def self.get_instance_params(**kwargs)
68
+ params = super(**kwargs)
69
+ params[:ISOAlpha2Code] = kwargs[:iso_alpha2_code] || ''
70
+ params[:Region] = kwargs[:region] || ''
71
+ params
72
+ end
73
+
74
+ end
75
+
76
+
77
+ # Represents a nationality in the LUSI API
78
+ # @see Country
79
+ class Nationality < Country
80
+
81
+ # Returns Nationality instances matching the specified parameters
82
+ # @param api [LUSI::API::Core::API] the LUSI API instance
83
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
84
+ # @param identity [String, nil] the identity to search for
85
+ # @param description [String, nil] the description to search for
86
+ # @param iso_alpha2_code [String, nil] the ISO alpha-2 code to search for
87
+ # @return [Array<Nationality>, nil] the matching Nationality instances
88
+ # @yield [obj] Passes the Nationality instance to the block
89
+ # @yieldparam obj [LUSI::API::Country::Nationality] the Nationality instance
90
+ def self.get_instance(api = nil, lookup = nil, iso_alpha2_code: nil, **kwargs)
91
+ super(api, lookup, 'LUSIReference', 'Lookup.asmx', 'GetNationalities', 'xmlns:Nationality',
92
+ iso_alpha2_code: iso_alpha2_code, **kwargs)
93
+ end
94
+
95
+ protected
96
+
97
+ # Returns a parameter hash for the LUSI API call
98
+ # @param (see #get_instance)
99
+ # @param iso_alpha2_code [String, nil] the ISO alpha-2 code to search for
100
+ # @return [Hash<String, any>] the parameter hash for the LUSI API call
101
+ def self.get_instance_params(iso_alpha2_code: nil, **kwargs)
102
+ params = super(**kwargs)
103
+ params[:ISOAlpha2Code] = kwargs[:iso_alpha2_code] || ''
104
+ params
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,1300 @@
1
+ require 'lusi_api/core/code'
2
+ require 'lusi_api/core/xml'
3
+ require 'lusi_api/enrolment'
4
+ require 'lusi_api/organisation'
5
+ require 'lusi_api/person/staff'
6
+
7
+
8
+ module LUSI
9
+ module API
10
+ module Course
11
+
12
+ public
13
+
14
+ # Represents the identity of a module or scheme of study
15
+ class Identity
16
+
17
+ # @!attribute [rw] asp
18
+ # @return [String, nil] the academically-significant period (ASP)
19
+ attr_accessor :asp
20
+
21
+ # @!attribute [rw] course
22
+ # @return [String, nil] the identity code of the module or scheme of study
23
+ attr_accessor :course
24
+
25
+ # @!attribute [rw] year
26
+ # @return [String, nil] the identity code of the academic year
27
+ attr_accessor :year
28
+
29
+ # Initialises a new Identity instance
30
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the identity
31
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
32
+ # @param asp [String, nil] the default academically-significant period (ASP)
33
+ # @param course [String, nil] the default identity of the module or schemem of study
34
+ # @param year [String, nil] the default academic year identity code
35
+ # @return [void]
36
+ def initialize(xml = nil, lookup = nil, asp: nil, course: nil, year: nil)
37
+ @asp = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:ASP', asp)
38
+ @course = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Course', course)
39
+ @year = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Year', year)
40
+ end
41
+
42
+ # Returns a string suitable for use as a hash lookup key
43
+ # @return [String] the lookup key
44
+ def lookup_key
45
+ "#{course}-#{year}"
46
+ end
47
+
48
+ # Returns a string representation of the Identity instance
49
+ # @return [String] the string representation of the Identity instance
50
+ def to_s
51
+ "lusi-#{lookup_key}"
52
+ end
53
+
54
+ end
55
+
56
+
57
+ # Represents a module or scheme of study enrolment identity in the LUSI API
58
+ class EnrolmentIdentity < Identity
59
+
60
+ # @!attribute [rw] cohort
61
+ # @return [Integer, nil] the identity code of the cohort for this course instance
62
+ attr_accessor :cohort
63
+
64
+ # Initialises a new EnrolmentIdentity instance
65
+ # @param (see LUSI::API::Course::Identity)
66
+ # @param cohort [Integer, nil] the default cohort identity code
67
+ # @return [void]
68
+ def initialize(xml = nil, lookup = nil, cohort: nil, **kwargs)
69
+ super(xml, lookup, **kwargs)
70
+ @cohort = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Cohort', cohort)
71
+ end
72
+
73
+ # (see LUSI::API::Course::Identity#lookup_key)
74
+ def lookup_key
75
+ "#{super}-#{cohort}"
76
+ end
77
+
78
+ end
79
+
80
+
81
+ # The abstract base class of Module and SchemeOfStudy
82
+ # @abstract Subclass and define:
83
+ # identity_class = the class representing identity
84
+ # lusi_ws_endpoint = the LUSI API endpoint
85
+ # lusi_ws_method = the LUSI API method to retrieve instance data
86
+ # lusi_ws_path = the LUSI API URL path
87
+ # lusi_ws_xml_root = the root element name of the LUSI API XML response
88
+ class ModuleBase
89
+
90
+ extend LUSI::API::Core::Endpoint
91
+
92
+ # @!attribute [rw] category_level
93
+ # @return [String, nil] the category (e.g. 'UG', 'PG')
94
+ attr_accessor :category_level
95
+
96
+ # @!attribute [rw] cohorts
97
+ # @return [Array<LUSI::API::Course::Cohort>, nil] the list of associated cohorts
98
+ attr_accessor :cohorts
99
+
100
+ # @!attribute [rw] course_departments
101
+ # @return [Array<LUSI::API::Course::CourseDepartment>, nil] the list of associated course departments
102
+ attr_accessor :course_departments
103
+
104
+ # @!attribute [rw] course_documents
105
+ # @return [Array<LUSI::API::Course::CourseDocument>, nil] the list of associated course documents
106
+ attr_accessor :course_documents
107
+
108
+ # @!attribute [rw] credit
109
+ # @return [String, nil] the credit point value
110
+ attr_accessor :credit
111
+
112
+ # @!attribute [rw] delivery_mode
113
+ # @return [LUSI::API::Core::Code, nil] the mode of delivery
114
+ attr_accessor :delivery_mode
115
+
116
+ # @!attribute [rw] display_long_title
117
+ # @return [String, nil] the long course title
118
+ attr_accessor :display_long_title
119
+
120
+ # @!attribute [rw] display_short_title
121
+ # @return [String, nil] the short course title
122
+ attr_accessor :display_short_title
123
+
124
+ # @!attribute [rw] enrolled_students
125
+ # @return [Integer, nil] the number of enrolled students
126
+ attr_accessor :enrolled_students
127
+
128
+ # @!attribute [rw] external_course_identity
129
+ # @return [String, nil] the external course identity
130
+ attr_accessor :external_course_identity
131
+
132
+ # @!attribute [rw] identity
133
+ # @return [LUSI::API::Course::Identity, nil] the course identity
134
+ attr_accessor :identity
135
+
136
+ # @!attribute [r] identity_class
137
+ # @return [Class, nil] the class representing module/scheme of study identity
138
+ attr_reader :identity_class
139
+
140
+ # @!attribute [rw] learning_hours
141
+ # @return [Integer, nil] the total number of learning hours
142
+ attr_accessor :learning_hours
143
+
144
+ # @!attribute [rw] mnemonic
145
+ # @return [String, nil] the mnemonic for the course
146
+ attr_accessor :mnemonic
147
+
148
+ # @!attribute [rw] status
149
+ # @return [String, nil] the status ('Live', 'Dormant', 'Draft' etc.)
150
+ attr_accessor :status
151
+
152
+ # @!attribute [rw] syllabus_rules
153
+ # @return [Array<LUSI::API::Course::SyllabusRule>, nil] the list of associated syllabus rules
154
+ attr_accessor :syllabus_rules
155
+
156
+ # @!attribute [rw] teaching_institution
157
+ # @return [LUSI::API::Organisation::Unit, nil] the teaching institution
158
+ attr_accessor :teaching_institution
159
+
160
+ # @!attribute [rw] title
161
+ # @return [String, nil] the title
162
+ attr_accessor :title
163
+
164
+ # @!attribute [rw] year
165
+ # @return [String, nil] the academic year
166
+ attr_accessor :year
167
+
168
+ # Returns an array of enrolment lookup table indices to search for this module/scheme of study
169
+ def enrolment_lookup_indices
170
+ []
171
+ end
172
+
173
+ # Returns an array of enrolment lookup table keys for this module/scheme of study
174
+ # @return [Array<String>] the enrolment lookup table keys
175
+ def enrolment_lookup_keys
176
+ self.cohorts.map { |cohort| "#{self.identity.lookup_key}-#{cohort.identity}" }
177
+ end
178
+
179
+ # Returns an array of instances matching the specified search criteria
180
+ # @param api [LUSI::API::Core::API] the LUSI API instance to use for searching
181
+ # @param (see #get_instance_params)
182
+ # @return [<Array<LUSI::API::Course::Module, LUSI::API::Course::SchemeOfStudy>] the list of matching instances
183
+ # @yield [obj] Passes the instance to the block
184
+ # @yieldparam obj [LUSI::API::Course::Module, LUSI::API::Course::SchemeOfStudy] the instance
185
+ def self.get_instance(api, lookup = nil, **kwargs)
186
+ # active_vle_spaces_only: nil)
187
+ params = get_instance_params(**kwargs)
188
+ xml = api.call(self.lusi_ws_path, self.lusi_ws_endpoint, self.lusi_ws_method, **params)
189
+ LUSI::API::Core::XML.xml(xml, "xmlns:#{self.lusi_ws_xml_root}") do |m|
190
+ obj = self.new(m, lookup)
191
+ yield(obj) if block_given?
192
+ obj
193
+ end
194
+ end
195
+
196
+ # Initialises a new ModuleBase instance
197
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the module or scheme of study
198
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
199
+ # @param category_level [String, nil] the default category
200
+ # @param cohort [LUSI::API::Course::Cohort, nil] the default cohort
201
+ # @param course_departments [Array<LUSI::API::Course::CourseDepartment>, nil] the default course departments
202
+ # @param course_documents [Array<LUSI::API::Course::CourseDocument>, nil] the default course documents
203
+ # @param credit [String, nil] the default credit point value
204
+ # @param delivery_mode [LUSI::API::Core::Code, nil] the default delivery mode
205
+ # @param display_long_title [String, nil] the default long title
206
+ # @param display_short_title [String, nil] the default short title
207
+ # @param enrolled_students [Integer, nil] the default number of enrolled students
208
+ # @param external_course_identity [String, nil] the default external course identity code
209
+ # @param identity [String, nil] the default identity code
210
+ # @param learning_hours [Integer, nil] the default number of learning hours
211
+ # @param mnemonic [String, nil] the default mnemonic
212
+ # @param subjects [Array<LUSI::API::Course::Subject>, nil] the default subjects
213
+ # @param status [String, nil] the default status
214
+ # @param syllabus_rules [Array<SyllabusRule>, nil] the default syllabus rules
215
+ # @param teaching_institution [LUSI::API::Organisation::Unit, nil] the default teaching institution
216
+ # @param title [String, nil] the default title
217
+ # @param year [String, nil] the default year
218
+ # @return [void]
219
+ def initialize(xml = nil, lookup = nil, category_level: nil, cohort: nil, course_departments: nil,
220
+ course_documents: nil, credit: nil, delivery_mode: nil, display_long_title: nil,
221
+ display_short_title: nil, enrolled_students: nil, external_course_identity: nil, identity: nil,
222
+ learning_hours: nil, mnemonic: nil, subjects: nil, status: nil, syllabus_rules: nil,
223
+ teaching_institution: nil, title: nil, year: nil)
224
+ @category_level = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:CategoryLevel', category_level)
225
+ @cohorts = LUSI::API::Core::XML.xml(xml, 'xmlns:Cohorts/xmlns:Cohort', cohort) { |c| Cohort.new(c, lookup) }
226
+ @course_departments = LUSI::API::Core::XML.xml(xml, 'xmlns:CourseDepartments/xmlns:CourseDepartment',
227
+ course_departments) { |d| CourseDepartment.new(d, lookup) }
228
+ @course_documents = LUSI::API::Core::XML.xml(xml, 'xmlns:CourseDocuments/xmlns:CourseDocument',
229
+ course_documents) { |c| CourseDocument.new(c, lookup) }
230
+ @credit = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Credit', credit)
231
+ @delivery_mode = LUSI::API::Core::Code.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:DeliveryMode',
232
+ delivery_mode), lookup)
233
+ @display_long_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayLongTitle', display_long_title)
234
+ @display_short_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayShortTitle',
235
+ display_short_title)
236
+ @external_course_identity = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:ExternalCourseIdentity',
237
+ external_course_identity)
238
+ @identity = Identity.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Identity', identity), lookup)
239
+ @learning_hours = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:LearningHours', learning_hours)
240
+ @mnemonic = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Mnemonic', mnemonic)
241
+ @status = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Status', status)
242
+ @subjects = LUSI::API::Core::XML.xml(xml, 'xmlns:Subjects/xmlns:Subject', subjects) { |s| Subject.new(s, lookup) }
243
+ @syllabus_rules = LUSI::API::Core::XML.xml(xml, 'xmlns:SyllabusRules/xmlns:SyllabusRule',
244
+ syllabus_rules) { |s| SyllabusRule.new(s, lookup) }
245
+ @teaching_institution = LUSI::API::Core::XML.lookup(xml, lookup, :institution,
246
+ 'xmlns:TeachingInstitution/xmlns:Identity',
247
+ teaching_institution)
248
+ @title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Title', title)
249
+ @year = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Year', year)
250
+ end
251
+
252
+
253
+ # Returns a hash of parameters for the LUSI API call. Subclasses may extend or override this method.
254
+ # @param asp_identity [String, nil] return instances matching this academic significant period (ASP)
255
+ # @param cohort_identity (String, nil) return instances matching this cohort identity
256
+ # @param course_identity [String, nil] return instances matching this course identity
257
+ # @param department_identity (String, nil) return instances matching this department identity
258
+ # @param external_course_identity [String, nil] return instances matching this external course identity
259
+ # @param include_course_documentation [Boolean, nil] include course documentation if true, otherwise omit it
260
+ # @param include_syllabus_rules [Boolean, nil] include syllabus rules if true, otherwise omit them
261
+ # @param live_only [Boolean, nil] return only live (active) instances if true, otherwise return all instances
262
+ # @param teaching_institution_id (String, nil) return instances matching this teaching institution
263
+ # @param year_identity (String, nil) return instances matching this year identity
264
+ # @return [Hash<String, String>] the parameter hash for the LUSI API call
265
+ def self.get_instance_params(**kwargs)
266
+ result = {
267
+ ASPIdentity: kwargs.fetch(:asp_identity, ''),
268
+ CohortIdentity: kwargs.fetch(:cohort_identity, ''),
269
+ CourseIdentity: kwargs.fetch(:course_identity, ''),
270
+ DepartmentIdentity: kwargs.fetch(:department_identity, ''),
271
+ ExternalCourseIdentity: kwargs.fetch(:external_course_identity, ''),
272
+ IncludeCourseDocumentation: kwargs.fetch(:include_course_documentation, false) ? 'true' : 'false',
273
+ IncludeSyllabusRules: kwargs.fetch(:include_syllabus_rules, false) ? 'true' : 'false',
274
+ LiveOnly: kwargs.fetch(:live_only, true) ? 'true' : 'false',
275
+ TeachingInstitutionId: kwargs.fetch(:teaching_institution_id, ''),
276
+ YearIdentity: kwargs.fetch(:year_identity, '')
277
+ }
278
+ if self.lusi_ws_endpoint == 'General.asmx'
279
+ # The General.asmx endpoint methods GetModuleDetails and GetSchemesOfStudy require an extra parameter
280
+ result[:ActiveVLESpaceOnly] = kwargs.fetch(:active_vle_space_only, true) ? 'true' : 'false'
281
+ end
282
+ result
283
+ end
284
+
285
+ #
286
+ # Returns the major departments for the module/scheme of study
287
+ # @return [Array<LUSI::API::Course::CourseDepartment>] the major departments
288
+ def major_departments
289
+ self.course_departments.select { |course_department| course_department.is_major_department }
290
+ end
291
+
292
+ protected
293
+
294
+ # Returns the class representing module/scheme of study identity
295
+ # @return [Class] the identity class
296
+ def self.identity_class
297
+ Identity
298
+ end
299
+
300
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_endpoint)
301
+ def self.lusi_ws_endpoint
302
+ 'CourseManager.asmx'
303
+ end
304
+
305
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_path)
306
+ def self.lusi_ws_path
307
+ 'LUSIReference'
308
+ end
309
+
310
+ end
311
+
312
+
313
+ #
314
+ #
315
+ # # The base class of ModuleEnrolment and SchemeOfStudyEnrolment
316
+ # class ModuleEnrolmentBase
317
+ #
318
+ # # @!attribute [rw] module_identity
319
+ # # @return [LUSI::API::Course::EnrolmentIdentity, nil] the module identity
320
+ # attr_accessor :identity
321
+ #
322
+ # # @!attribute [rw] display_long_title
323
+ # # @return [String, nil] the long title of the module
324
+ # attr_accessor :display_long_title
325
+ #
326
+ # # @!attribute [rw] display_short_title
327
+ # # @return [String, nil] the short title of the module
328
+ # attr_accessor :display_short_title
329
+ #
330
+ # # @!attribute [rw] enrol_year
331
+ # # @return [String, nil] the year of enrolment
332
+ # attr_accessor :enrol_year
333
+ #
334
+ # # @!attribute [rw] mnemonic
335
+ # # @return [String, nil] the mnemonic of the module
336
+ # attr_accessor :mnemonic
337
+ #
338
+ # # @!attribute [rw] title
339
+ # # @return [String, nil] the title of the module
340
+ # attr_accessor :title
341
+ #
342
+ # # @!attribute [rw] cohort_end_date
343
+ # # @return [DateTime, nil] the end date of the cohort in local time
344
+ # attr_accessor :cohort_end_date
345
+ #
346
+ # # @!attribute [rw] cohort_end_date_utc
347
+ # # @return [DateTime, nil] the end date of the cohort in UTC
348
+ # attr_accessor :cohort_end_date_utc
349
+ #
350
+ # # @!attribute [rw] cohort_start_date
351
+ # # @return [DateTime, nil] the start date of the cohort in local time
352
+ # attr_accessor :cohort_start_date
353
+ #
354
+ # # @!attribute [rw] cohort_start_date_utc
355
+ # # @return [DateTime, nil] the start date of the cohort in UTC
356
+ # attr_accessor :cohort_start_date_utc
357
+ #
358
+ # # Initialises a new ModuleEnrolment instance
359
+ # # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the module enrolment
360
+ # # @param lookup [LUSI::API::Core::LookupTable, nil] the lookup service for object resolution
361
+ # # @param student_identity [String, nil] the default student identity
362
+ # # @param identity [LUSI::API::Course::EnrolmentIdentity, nil] the default enrolment identity
363
+ # # @param display_long_title [String, nil] the default module long title
364
+ # # @param display_short_title [String, nil] the default module short title
365
+ # # @param enrol_year [String, nil] the default enrol year
366
+ # # @param mnemonic [String, nil] the default module mnemonic
367
+ # # @param title [String, nil] the default module title
368
+ # # @param cohort_end_date [DateTime, nil] the default local-time cohort end date
369
+ # # @param cohort_end_date_utc [DateTime, nil] the default UTC cohort end date
370
+ # # @param cohort_start_date [DateTime, nil] the default local-time codhort start date
371
+ # # @param cohort_start_date_utc [DateTime, nil] the default UTC cohort start date
372
+ # # @return [void]
373
+ # def initialize(xml = nil, lookup = nil, student_identity: nil, identity: nil, display_long_title: nil,
374
+ # display_short_title: nil, enrol_year: nil, mnemonic: nil, title: nil, department: nil,
375
+ # year_sos: nil, study_type: nil, talis_code: nil, cohort_end_date: nil, cohort_end_date_utc: nil,
376
+ # cohort_start_date: nil, cohort_start_date_utc: nil)
377
+ # @student_identity = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:StudentIdentity', student_identity)
378
+ # @identity = EnrolmentIdentity.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Identity', identity), lookup)
379
+ # @display_long_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayLongTitle', display_long_title)
380
+ # @display_short_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayShortTitle',
381
+ # display_short_title)
382
+ # @enrol_year = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:EnrolYear', enrol_year)
383
+ # @mnemonic = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Mnemonic', mnemonic)
384
+ # @title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Title', title)
385
+ # @cohort_end_date = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:CohortEndDate', cohort_end_date)
386
+ # @cohort_end_date_utc = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:CohortEndDateUTC',
387
+ # cohort_end_date_utc)
388
+ # @cohort_start_date = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:CohortStartDate', cohort_start_date)
389
+ # @cohort_start_date_utc = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:CohortStartDateUTC',
390
+ # cohort_start_date_utc)
391
+ # end
392
+ #
393
+ # end
394
+
395
+
396
+ # Mixin for staff user details
397
+ module StaffEndpoint
398
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_path)
399
+ def lusi_ws_endpoint
400
+ 'Staff.asmx'
401
+ end
402
+ end
403
+
404
+
405
+ # Mixin for student user details
406
+ module StudentEndpoint
407
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_path)
408
+ def lusi_ws_endpoint
409
+ 'Student.asmx'
410
+ end
411
+ end
412
+
413
+
414
+ public
415
+
416
+ # Represents a module assessment proportion in the LUSI API
417
+ class AssessmentProportion
418
+
419
+ # @!attribute [rw] assessment_type
420
+ # @return [LUSI::API::Core::Code, nil] the assessment type
421
+ attr_accessor :assessment_type
422
+
423
+ # @!attribute [rw] percentage
424
+ # @return [Integer, nil] the percentage value
425
+ attr_accessor :percentage
426
+
427
+ # @!attribute [rw] assessment_status
428
+ # @return [LUSI::API::Core::Code, nil] the assessment status
429
+ attr_accessor :assessment_status
430
+
431
+ # Initialises a new AssessmentProportion instance
432
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the assessment proportion
433
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
434
+ # @param assessment_status [LUSI::API::Core::Code, nil] the default assessment status
435
+ # @param assessment_type [LUSI::API::Core::Code, nil] the default assessment_type
436
+ # @param percentage [Integer, nil] the default percentage value
437
+ # @return [void]
438
+ def initialize(xml = nil, lookup = nil, assessment_status: nil, assessment_type: nil, percentage: nil)
439
+ @assessment_status = LUSI::API::Core::Code.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:AssessmentStatus',
440
+ assessment_status), lookup)
441
+ @assessment_type = LUSI::API::Core::Code.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:AssessmentType',
442
+ assessment_type), lookup)
443
+ @percentage = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Percentage', percentage)
444
+ end
445
+
446
+ # Returns a string representation of the AssessmentProportion instance
447
+ # @return [String] the string representation of the AssessmentProportion instance
448
+ def to_s
449
+ "#{@assessment_type.description} #{percentage}%"
450
+ end
451
+
452
+ end
453
+
454
+
455
+ # Represents a cohort (student intake) in the LUSI API
456
+ class Cohort
457
+
458
+ # @!attribute [rw] display_long_title
459
+ # @return [String, nil] the long title of the cohort
460
+ attr_accessor :display_long_title
461
+
462
+ # @!attribute [rw] display_short_title
463
+ # @return [String, nil] the short title of the cohort
464
+ attr_accessor :display_short_title
465
+
466
+ # @!attribute [rw] end_date
467
+ # @return [DateTime, nil] the end date of study
468
+ attr_accessor :end_date
469
+
470
+ # @!attribute [rw] identity
471
+ # @return [Integer, nil] the identity code of the cohort
472
+ attr_accessor :identity
473
+
474
+ # @!attribute [rw] start_date
475
+ # @return [DateTime, nil] the start date of study
476
+ attr_accessor :start_date
477
+
478
+ # Initialises a new Cohort instance
479
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the cohort
480
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
481
+ # @param display_long_title [String, nil] the default long title
482
+ # @param display_short_title [String, nil] the default short title
483
+ # @param end_date [DateTime, nil] the default end-of-study date
484
+ # @param identity [Integer, nil] the default identity code
485
+ # @param start_date [DateTime, nil] the default start-of-study date
486
+ # @return [void]
487
+ def initialize(xml = nil, lookup = nil, display_long_title: nil, display_short_title: nil, end_date: nil,
488
+ identity: nil, start_date: nil)
489
+ @display_long_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayLongTitle', display_long_title)
490
+ @display_short_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayShortTitle', display_short_title)
491
+ @end_date = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:EndDate', end_date)
492
+ @identity = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Identity', identity)
493
+ @start_date = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:StartDate', start_date)
494
+ end
495
+
496
+ # Returns a string representation of the Cohort instance
497
+ # @return [String] the string representation of the Cohort instance
498
+ def to_s
499
+ end_date = @end_date ? @end_date.strftime('%d-%m-%Y') : ''
500
+ start_date = @start_date ? @start_date.strftime('%d-%m-%Y') : ''
501
+ "#{@display_long_title || @display_short_title} #{start_date}-#{end_date}"
502
+ end
503
+
504
+ end
505
+
506
+
507
+ # Represents a department participating in a course
508
+ class CourseDepartment
509
+
510
+ # @!attribute [rw] org_unit
511
+ # @return [LUSI::API::Organisation::Unit] the organisation unit representing the department
512
+ attr_accessor :org_unit
513
+
514
+ # @!attribute [rw] identity
515
+ # @return [String] the course department identity code
516
+ attr_accessor :identity
517
+
518
+ # @!attribute [rw] is_major_department
519
+ # @return [Boolean] true if the department is the major (administering) department, otherwise false
520
+ attr_accessor :is_major_department
521
+
522
+ # @!attribute [rw] title
523
+ # @return [String] the course department's title
524
+ attr_accessor :title
525
+
526
+ # Initialises a new CourseDepartment instance
527
+ # @param identity [String] the course department's identity code
528
+ # @param org_unit [LUSI::API::Organisation::Unit] the default organisation unit for the department
529
+ # @param is_major_department [Boolean, nil] the major (administering) department flag
530
+ # @param title [String] the course department's title
531
+ # @return [void]
532
+ def initialize(xml = nil, lookup = nil, identity: nil, is_major_department: nil, org_unit: nil, title: nil)
533
+ is_major_department = is_major_department ? true : false
534
+ @identity = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Identity', identity)
535
+ @is_major_department = LUSI::API::Core::XML.xml_boolean_at(xml, 'xmlns:IsMajorDepartment', is_major_department)
536
+ @org_unit = LUSI::API::Core::XML.lookup(xml, lookup, :department, 'xmlns:Identity', org_unit)
537
+ @title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Title', title)
538
+ end
539
+
540
+ end
541
+
542
+
543
+ # Represents a course document in the LUSI API
544
+ class CourseDocument
545
+
546
+ # @!attribute [rw] type
547
+ # @return [LUSI::API::Core::Code, nil] the course document type
548
+ attr_accessor :type
549
+
550
+ # @!attribute [rw] html_text
551
+ # @return [String, nil] the text document as pre-formatted HTML
552
+ attr_accessor :html_text
553
+
554
+ # Initialises a new CourseDocument instance
555
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the course document
556
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
557
+ # @param type [LUSI::API::Core::Code, nil] the default document type
558
+ # @param html_text [String, nil] the default document text
559
+ # @return [void]
560
+ def initialize(xml = nil, lookup = nil, type: nil, html_text: nil)
561
+ @type = LUSI::API::Core::Code.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Type', type), lookup)
562
+ @html_text = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:HTMLText', html_text)
563
+ end
564
+
565
+ # Returns a string representation of the CourseDocument instance
566
+ # @return [String] the string representation of the CourseDocument instance
567
+ def to_s
568
+ @type.description
569
+ end
570
+
571
+ end
572
+
573
+
574
+ # Represents the credit points for a scheme of study
575
+ class CreditPoints
576
+
577
+ # @!attribute [rw] total_part_1
578
+ # @return [Integer, nil] the total number of credit points required at Part 1
579
+ attr_accessor :total_part_1
580
+
581
+ # @!attribute [rw] part_2_year_2
582
+ # @return [Integer, nil] the number of Part 2 credit points required in year 2
583
+ attr_accessor :part_2_year_2
584
+
585
+ # @!attribute [rw] part_2_year_3
586
+ # @return [Integer, nil] the number of Part 2 credit points required in year 3
587
+ attr_accessor :part_2_year_3
588
+
589
+ # @!attribute [rw] part_2_year_4
590
+ # @return [Integer, nil] the number of Part 2 credit points required in year 4
591
+ attr_accessor :part_2_year_4
592
+
593
+ # @!attribute [rw] part_2_year_5
594
+ # @return [Integer, nil] the number of Part 2 credit points required in year 5
595
+ attr_accessor :part_2_year_5
596
+
597
+ # @!attribute [rw] total_part_2
598
+ # @return [Integer, nil] the total number of credit points required at Part 2
599
+ attr_accessor :total_part_2
600
+
601
+ # @!attribute [rw] total_overall
602
+ # @return [Integer, nil] the total number of credit points required for the scheme of study
603
+ attr_accessor :total_overall
604
+
605
+ # Initialises a new CreditPoints instance
606
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the credit points
607
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
608
+ # @param part_2_year_2 [Integer, nil] the default part 2 year 2 credit points
609
+ # @param part_2_year_3 [Integer, nil] the default part 2 year 3 credit points
610
+ # @param part_2_year_4 [Integer, nil] the default part 2 year 4 credit points
611
+ # @param part_2_year_5 [Integer, nil] the default part 2 year 5 credit points
612
+ # @param total_overall [Integer, nil] the default overall total credit points
613
+ # @param total_part_1 [Integer, nil] the default part 1 total credit points
614
+ # @param total_part_2 [Integer, nil] the default part 2 total
615
+ # @return [void]
616
+ def initialize(xml = nil, lookup = nil, part_2_year_2: 0, part_2_year_3: 0, part_2_year_4: 0, part_2_year_5: 0,
617
+ total_overall: 0, total_part_1: 0, total_part_2: 0)
618
+ @part_2_year_2 = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Part2Year2', part_2_year_2)
619
+ @part_2_year_3 = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Part2Year3', part_2_year_3)
620
+ @part_2_year_4 = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Part2Year4', part_2_year_4)
621
+ @part_2_year_5 = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:Part2Year5', part_2_year_5)
622
+ @total_overall = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:TotalOverall', total_overall)
623
+ @total_part_1 = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:TotalPart1', total_part_1)
624
+ @total_part_2 = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:TotalPart2', total_part_2)
625
+ end
626
+
627
+ # Returns a string representation of the CreditPoints instance
628
+ # @return [String] the string representation of the CreditPoints instance
629
+ def to_s
630
+ "#{@total_overall}"
631
+ end
632
+
633
+ end
634
+
635
+
636
+ # Represents the length of a scheme of study
637
+ class Length
638
+
639
+ # @!attribute [rw] absolute_maximum
640
+ # @return [String, nil] the absolute maximum scheme length
641
+ attr_accessor :absolute_maximum
642
+
643
+ # @!attribute [rw] maximum
644
+ # @return [String, nil] the maximum scheme length
645
+ attr_accessor :maximum
646
+
647
+ # @!attribute [rw] minimum
648
+ # @return [String, nil] the minimum scheme length
649
+ attr_accessor :minimum
650
+
651
+ # Initialises a new Length instance
652
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the length
653
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
654
+ # @param absolute_maximum [String, nil] the default absolute maximum scheme length
655
+ # @param maximum [String, nil] the default maximum scheme length
656
+ # @param minimum [String, nil] the default minimum scheme length
657
+ # @return [void]
658
+ def initialize(xml = nil, lookup = nil, absolute_maximum: nil, maximum: nil, minimum: nil)
659
+ @absolute_maximum = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:AbsoluteMaximum', absolute_maximum)
660
+ @maximum = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Maximum', maximum)
661
+ @minimum = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Minimum', minimum)
662
+ end
663
+
664
+ # Returns a string representation of the Length instance
665
+ # @return [String] the string representation of the SchemeLength instance
666
+ def to_s
667
+ "#{minimum} - #{maximum} (#{absolute_maximum})"
668
+ end
669
+
670
+ end
671
+
672
+
673
+ # Represents a module mark in the LUSI API
674
+ class Mark
675
+
676
+ # @!attribute [rw] overall_percentage
677
+ # @return [Float, nil] the overall percentage mark for the module
678
+ attr_accessor :overall_percentage
679
+
680
+ # @!attribute [rw] overall_aggregation
681
+ # @return [Float, nil] the overall aggregation score for the module
682
+ attr_accessor :overall_aggregation
683
+
684
+ # Initialises a new Mark instance
685
+ # @param xml [Nokogir::XML::Document, Nokogiri::XML::Node] the parsed XML root of the mark
686
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
687
+ # @param overall_aggregation [Float, int] the default overall aggregation
688
+ # @param overall_percentage [Float, int] the default overall percentage
689
+ # @return [void]
690
+ def initialize(xml = nil, lookup = nil, overall_percentage: nil, overall_aggregation: nil)
691
+ @overall_percentage = LUSI::API::Core::XML.xml_float_at(xml, 'xmlns:OverallPercentage', overall_percentage)
692
+ @overall_aggregation = LUSI::API::Core::XML.xml_float_at(xml, 'xmlns:OverallAggregation',
693
+ overall_aggregation)
694
+ end
695
+
696
+ # Returns a string representation of the Mark instance
697
+ # @return [String] the string representation of the Mark instance
698
+ def to_s
699
+ "#{@overall_aggregation} (#{@overall_percentage}%)"
700
+ end
701
+
702
+ end
703
+
704
+
705
+ # # Represents a module enrolment in the LUSI API
706
+ # class ModuleEnrolment < ModuleEnrolmentBase
707
+ #
708
+ # # @!attribute [rw] module_identity
709
+ # # @see (#identity)
710
+ # alias module_identity identity
711
+ #
712
+ # # @!attribute [rw] department
713
+ # # @return [LUSI::API::Organisation::Unit, nil] the major department
714
+ # attr_accessor :department
715
+ #
716
+ # # @!attribute [rw] year_sos
717
+ # # @return [Integer, nil] the year of study on the scene(1 = first year etc.)
718
+ # attr_accessor :year_sos
719
+ #
720
+ # # @!attribute [rw] study_type
721
+ # # @return [String, nil] the type of study (e.g. 'Major', 'Minor')
722
+ # attr_accessor :study_type
723
+ #
724
+ # # @!attribute [rw] talis_code
725
+ # # @return [String, nil] the Talis Aspire reading list code
726
+ # attr_accessor :talis_code
727
+ #
728
+ # # @!attribute [rw] mark
729
+ # # @return [LUSI::API::Course::Mark, nil] the mark for the module
730
+ # attr_accessor :mark
731
+ #
732
+ # # Initalises a new ModuleEnrolment instance
733
+ # # @param (see LUSI::API::Course::ModuleEnrolmentBase#initialize)
734
+ # # @param department [LUSI::API::Organisation::Unit] the default major department
735
+ # # @param year_sos [Integer, nil] the default year of scheme of study
736
+ # # @param study_type [String, nil] the default study type
737
+ # # @param talis_code [String, nil] the default Talis Aspire reading list code
738
+ # # @param mark [LUSI::API::Course::Mark, nil] the default mark for the module
739
+ # # @return [void]
740
+ # def initialize(xml = nil, lookup = nil, department: nil, year_sos: nil, study_type: nil, talis_code: nil,
741
+ # mark: nil, **kwargs)
742
+ # super(xml, lookup, **kwargs)
743
+ # @department = LUSI::API::Core::XML.lookup(xml, lookup, :department, 'xmlns:Department/xmlns:Identity',
744
+ # department)
745
+ # @year_sos = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:YearSos', year_sos)
746
+ # @study_type = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:StudyType', study_type)
747
+ # @talis_code = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:TalisCode', talis_code)
748
+ # @mark = Mark.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Mark', mark))
749
+ # end
750
+ #
751
+ # end
752
+
753
+
754
+ # The abstract base class for module/scheme of study enrolments
755
+ # @abstract Subclasses must implement lookup_index and alias :course_identity to the accessor for the
756
+ # subclass-specific identity.
757
+ class CourseEnrolment < LUSI::API::Enrolment::EnrolmentBase
758
+
759
+ # Returns the index name used for the module/scheme of study identity
760
+ # @return [Symbol] the module/scheme of study index name
761
+ def self.lookup_index
762
+ raise NotImplementedError
763
+ end
764
+
765
+ # @see (LUSI::API::Enrolment::EnrolmentBase#lookup_indices)
766
+ def lookup_indices
767
+ super.push(self.lookup_index)
768
+ end
769
+
770
+ # @see (LUSI::API::Enrolment::EnrolmentBase#lookup_key)
771
+ def lookup_key(index)
772
+ # self.course_identity should be defined by all subclasses
773
+ if index == self.lookup_index
774
+ self.course_identity.lookup_key
775
+ else
776
+ super(index)
777
+ end
778
+ end
779
+
780
+ end
781
+
782
+
783
+ # Represents a module enrolment in the LUSI API
784
+ class ModuleEnrolment < CourseEnrolment
785
+
786
+ # @!attribute [rw] module_identity
787
+ # @return [LUSI::API::Course::EnrolmentIdentity] the enrolment's module identity
788
+ attr_accessor :module_identity
789
+ alias :course_identity :module_identity
790
+
791
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_method)
792
+ def self.lusi_ws_method
793
+ 'BulkGetModuleEnrolments'
794
+ end
795
+
796
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_xml_root)
797
+ def self.lusi_ws_xml_root
798
+ 'BulkModuleEnrolment'
799
+ end
800
+
801
+ # @see (LUSI::API::Enrolment::EnrolmentBase#initialize)
802
+ # @param module_identity [LUSI::API::Course::EnrolmentIdentity] the enrolment's module identity
803
+ def initialize(xml = nil, lookup = nil, module_identity: nil, **kwargs)
804
+ super(xml, lookup, **kwargs)
805
+ @module_identity = EnrolmentIdentity.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:ModuleIdentity',
806
+ module_identity), lookup)
807
+ end
808
+
809
+ end
810
+
811
+
812
+ # Represents a module evaluation cohort in the LUSI API
813
+ class ModuleEvaluationCohort
814
+
815
+ # @!attribute [rw] cohort identity
816
+ # @return [String, nil] the identity code of the cohort
817
+ attr_accessor :cohort_identity
818
+
819
+ # @!attribute [rw] evaluation_date
820
+ # @return [DateTime, nil] the start date of module evaluation for the cohort
821
+ attr_accessor :evaluation_date
822
+
823
+ # @!attribute [rw] week_identity
824
+ # @return [String, nil] the starting week identity of module evaluation for the cohort
825
+ attr_accessor :week_identity
826
+
827
+ # Initialises a new ModuleEvaluationCohort instance
828
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the module evaluation cohort
829
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
830
+ # @param cohort_identity [String, nil] the default cohort identity code
831
+ # @param evaluation_date [DateTime, nil] the default evaluation start date
832
+ # @param week_identity [String, nil] the default evaluation start week identity
833
+ # @return [void]
834
+ def initialize(xml = nil, lookup = nil, cohort_identity: nil, evaluation_date: nil, week_identity: nil)
835
+ @cohort_identity = LUSI::API::Core::XML.xml_int_at(xml, 'xmlns:CohortIdentity', cohort_identity)
836
+ @evaluation_date = LUSI::API::Core::XML.xml_datetime_at(xml, 'xmlns:EvaluationDate', evaluation_date)
837
+ @week_identity = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:WeekIdentity', week_identity)
838
+ end
839
+
840
+ # Returns a string representation of the ModuleEvaluationCohort instance
841
+ # @return [String] the string representation of the ModuleEvaluationCohort instance
842
+ def to_s
843
+ "#{@cohort_identity}: #{@evaluation_date}"
844
+ end
845
+
846
+ end
847
+
848
+
849
+ # # Represents a scheme of study enrolment in the LUSI API
850
+ # class SchemeOfStudyEnrolment < ModuleEnrolmentBase
851
+ #
852
+ # # @!attribute [rw] qualification
853
+ # # @return [String, nil] the qualification (e.g. 'BSc Hons')
854
+ # attr_accessor :qualification
855
+ #
856
+ # # @!attribute [rw] mode_of_study
857
+ # # @return [String, nil] the mode of study (e.g. 'Full Time')
858
+ # attr_accessor :mode_of_study
859
+ #
860
+ # # @!attribute scheme_length
861
+ # # @return [String, nil] the length of the scheme of study
862
+ # attr_accessor :scheme_length
863
+ #
864
+ # # Initialises a new SchemeOfStudyEnrolment instance
865
+ # # @param (see LUSI::API::Course::ModuleEnrolmentBase#initialize)
866
+ # # @param qualification [String, nil] the default qualification
867
+ # # @param mode_of_study [String. nil] the default mode of study
868
+ # # @param scheme_length [String, nil] the default scheme length
869
+ # # @return [void]
870
+ # def initialize(xml = nil, lookup = nil, mode_of_study: nil, qualification: nil, scheme_length: nil, **kwargs)
871
+ # super(xml, lookup, **kwargs)
872
+ # @mode_of_study = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:ModeOfStudy', mode_of_study)
873
+ # @qualification = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Qualification', qualification)
874
+ # @scheme_length = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:SchemeLength', scheme_length)
875
+ # end
876
+ #
877
+ # end
878
+
879
+
880
+ # Represents a module enrolment in the LUSI API
881
+ class SchemeOfStudyEnrolment < CourseEnrolment
882
+
883
+ # @!attribute [rw] scheme_identity
884
+ # @return [LUSI::API::Course::EnrolmentIdentity] the enrolment's scheme of study identity
885
+ attr_accessor :scheme_identity
886
+ alias :course_identity :scheme_identity
887
+
888
+ # @see (LUSI::API::Course::CourseEnrolment#lookup_index)
889
+ def self.lookup_index
890
+ raise NotImplementedError
891
+ end
892
+
893
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_method)
894
+ def self.lusi_ws_method
895
+ 'BulkGetSchemeOfStudyEnrolments'
896
+ end
897
+
898
+ # @see (LUSI::API::Core::Endpoint#lusi_ws_xml_root)
899
+ def self.lusi_ws_xml_root
900
+ 'BulkSchemeOfStudyEnrolment'
901
+ end
902
+
903
+ # @see (LUSI::API::Enrolment::EnrolmentBase#initialize)
904
+ # @param scheme_identity [LUSI::API::Course::EnrolmentIdentity] the enrolment's scheme of study identity
905
+ def initialize(xml = nil, lookup = nil, scheme_identity: nil, **kwargs)
906
+ super(xml, lookup, **kwargs)
907
+ @scheme_identity = EnrolmentIdentity.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:SchemeIdentity',
908
+ scheme_identity), lookup)
909
+ end
910
+
911
+ end
912
+
913
+
914
+ # Represents a staff module enrolment in the LUSI API
915
+ class StaffModuleEnrolment < ModuleEnrolment
916
+
917
+ extend StaffEndpoint
918
+
919
+ # @see (LUSI::API::Course::ModuleEnrolment#lookup_index)
920
+ def lookup_index
921
+ :module_staff
922
+ end
923
+
924
+ end
925
+
926
+
927
+ # Represents a staff scheme of study enrolment in the LUSI API
928
+ class StaffSchemeOfStudyEnrolment < SchemeOfStudyEnrolment
929
+
930
+ extend StaffEndpoint
931
+
932
+ # @see (LUSI::API::Course::ModuleEnrolment#lookup_index)
933
+ def lookup_index
934
+ :scheme_staff
935
+ end
936
+
937
+ end
938
+
939
+
940
+ # Represents a student module enrolment in the LUSI API
941
+ class StudentModuleEnrolment < ModuleEnrolment
942
+
943
+ extend StudentEndpoint
944
+
945
+ # @see (LUSI::API::Course::ModuleEnrolment#lookup_index)
946
+ def lookup_index
947
+ :module_student
948
+ end
949
+
950
+ end
951
+
952
+
953
+ # Represents a student scheme of study enrolment in the LUSI API
954
+ class StudentSchemeOfStudyEnrolment < SchemeOfStudyEnrolment
955
+
956
+ extend StudentEndpoint
957
+
958
+ # @see (LUSI::API::Course::ModuleEnrolment#lookup_index)
959
+ def lookup_index
960
+ :scheme_student
961
+ end
962
+
963
+ end
964
+
965
+
966
+ # Represents a subject in the LUSI API
967
+ class Subject
968
+
969
+ # @!attribute [rw] identity
970
+ # @return [String, nil] the identity code of the subject
971
+ attr_accessor :identity
972
+
973
+ # @!attribute [rw] mnemonic
974
+ # @return [String, nil] the mnemonic for the subject
975
+ attr_accessor :mnemonic
976
+
977
+ # @!attribute [rw] title
978
+ # @return [String, nil] the title of the subject
979
+ attr_accessor :title
980
+
981
+ # @!attribute [rw] group
982
+ # @return [String, nil] the group type of the subject
983
+ attr_accessor :group
984
+
985
+ # @!attribute [rw] department
986
+ # @return [LUSI::API::Organisation::Unit, nil] the department associated with the subject
987
+ attr_accessor :department
988
+
989
+ # Initialises a new Subject instance
990
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the subject
991
+ # @param lookup [LUSI::API::Core::LookupTable, nil] the lookup table for department resolution
992
+ # @param department [LUSI::API::Organisation::Unit, nil] the default department
993
+ # @param group [String, nil] the default group type
994
+ # @param identity [String, nil] the default identity code
995
+ # @param mnemonic [String, nil] the default mnemonic
996
+ # @param title [String, title] the default title
997
+ # @return [void]
998
+ def initialize(xml = nil, lookup = nil, department: nil, group: nil, identity: nil, mnemonic: nil, title: nil)
999
+ @department = LUSI::API::Core::XML.lookup(xml, lookup, :department, 'xmlns:Department/xmlns:Identity',
1000
+ department)
1001
+ @group = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Group', group)
1002
+ @identity = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Identity', identity)
1003
+ @mnemonic = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Mnemonic', mnemonic)
1004
+ @title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Title', title)
1005
+ end
1006
+
1007
+ # Returns a string representation of the Subject instance
1008
+ # @return [String] the string representationn of the Subject instance
1009
+ def to_s
1010
+ @title
1011
+ end
1012
+
1013
+ end
1014
+
1015
+
1016
+ # Represents a syllabus rule in the LUSI API
1017
+ class SyllabusRuleModule
1018
+
1019
+ # @!attribute [rw] identity
1020
+ # @return [LUSI::API::Course::Identity, nil] the identity code of the associatied module or scheme of study
1021
+ attr_accessor :identity
1022
+
1023
+ # @!attribute [rw] display_long_title
1024
+ # @return [String, nil] the long title of the rule
1025
+ attr_accessor :display_long_title
1026
+
1027
+ # @!attribute [rw] display_short_title
1028
+ # @return [String, nil] the short title of the rule
1029
+ attr_accessor :display_short_title
1030
+
1031
+ # Initialises a new SyllabusRuleModule instance
1032
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the syllabus rule module
1033
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
1034
+ # @param identity [String, nil] the default identity code
1035
+ # @param display_long_title [String, nil] the default long title
1036
+ # @param display_short_title [String, nil] the default short title
1037
+ # @return [void]
1038
+ def initialize(xml = nil, lookup = nil, display_long_title: nil, display_short_title: nil, identity: nil)
1039
+ @display_long_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayLongTitle', display_long_title)
1040
+ @display_short_title = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:DisplayShortTitle', display_short_title)
1041
+ @identity = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Identity', identity)
1042
+ end
1043
+
1044
+ # Returns a string representation to the SyllabusRuleModule instance
1045
+ # @return [String] the string representation to the SyllabusRuleModule instance
1046
+ def to_s
1047
+ @display_long_title
1048
+ end
1049
+
1050
+ end
1051
+
1052
+
1053
+ # Represents a syllabus rule type in the LUSI API
1054
+ class SyllabusRuleType < LUSI::API::Core::Code
1055
+
1056
+ # @!attribute [rw] category
1057
+ # @return [String, nil] the rule type category (short description)
1058
+ attr_accessor :category
1059
+
1060
+ # Initialises a new SyllabusRuleType instance
1061
+ # @param (see LUSI::API::Core::Code)
1062
+ # @param category [String, nil] the default rule type category (short description)
1063
+ # @return [void]
1064
+ def initialize(xml = nil, lookup = nil, category: nil, **kwargs)
1065
+ super(xml, **kwargs)
1066
+ @category = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Category', category)
1067
+ end
1068
+
1069
+ # Returns a string representation of the SyllabusRuleType instance
1070
+ # @return [String] the string representation of the SyllabusRuleType instance
1071
+ def to_s
1072
+ "[#{@category}]: #{@description}"
1073
+ end
1074
+
1075
+ end
1076
+
1077
+
1078
+ # Represents a syllabus rule in the LUSI API
1079
+ class SyllabusRule
1080
+
1081
+ # @!attribute [rw] level
1082
+ # @return [String, nil] the level this rule applies to ('Module', 'Part II Year 3' etc.)
1083
+ attr_accessor :level
1084
+
1085
+ # @!attribute [rw] type
1086
+ # @return [LUSI::API::Course::SyllabusRuleType] the rule type
1087
+ attr_accessor :type
1088
+
1089
+ # @!attribute [rw] syllabus_rule_modules
1090
+ # @return [Array<LUSI::API::Course::SyllabusRuleModule>, nil] the list of modules included with this rule
1091
+ attr_accessor :syllabus_rule_modules
1092
+
1093
+ # Initialises a new SyllabusRule instance
1094
+ # @param xml [Nokogiri::XML::Document, Nokogiri::XML::Node] the parsed XML root of the syllabus rule
1095
+ # @param lookup [LUSI::API::Core::Lookup::LookupService, nil] the lookup service for object resolution
1096
+ # @param level [String, nil] the default rule level
1097
+ # @param type [LUSI::API::Course::SyllabusRuleType, nil] the default rule type
1098
+ # @param syllabus_rule_modules [Array<LUSI::API::Course::SyllabusRuleModule>, nil] the default rule modules
1099
+ # @return [void]
1100
+ def initialize(xml = nil, lookup = nil, level: nil, syllabus_rule_modules: nil, type: nil)
1101
+ @level = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Level', level)
1102
+ @syllabus_rule_modules = LUSI::API::Core::XML.xml(xml, 'xmlns:SyllabusRuleModuless/xmlns:SyllabusRuleModule',
1103
+ syllabus_rule_modules) { |s| SyllabusRuleModule.new(s, lookup) }
1104
+ @type = SyllabusRuleType.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Type', type), lookup)
1105
+ end
1106
+
1107
+ # Returns a string representation of the SyllabusRule instance
1108
+ # @return [String] the string representation of the SyllabusRule instance
1109
+ def to_s
1110
+ "#{@level} #{@type}"
1111
+ end
1112
+
1113
+ end
1114
+
1115
+
1116
+ # Represents a module in the LUSI API
1117
+ class Module < ModuleBase
1118
+
1119
+ # @!attribute [rw] assessment_proportions
1120
+ # @return [Array<LUSI::API::Course::AssessmentProportion>, nil] the assessment proportions for the module
1121
+ attr_accessor :assessment_proportions
1122
+
1123
+ # @!attribute [rw] course_convenors
1124
+ # @return [Array<LUSI::API::Person::StaffMember>] the course convenor(s)
1125
+ attr_accessor :course_convenors
1126
+
1127
+ # @!attribute [rw] lecture_capture_enabled
1128
+ # @return [Boolean, nil] true if automated lecture capture is available for the module, otherwise false
1129
+ attr_accessor :lecture_capture_enabled
1130
+
1131
+ # @!attribute [rw] module_evaluation_cohorts
1132
+ # @return [Array<LUSI::API::Course::ModuleEvaluationCohort>, nil] the evaluation cohorts for the module
1133
+ attr_accessor :module_evaluation_cohorts
1134
+
1135
+ # @!attribute [rw] partner_module_leaders
1136
+ # @return [Array<LUSI::API::Person::StaffMember>, nil] the staff members leading the module
1137
+ attr_accessor :partner_module_leaders
1138
+
1139
+ # @!attribute [rw] validating_institution
1140
+ # @return [LUSI::API::Organisation::Unit, nil] the validating institution for the module
1141
+ attr_accessor :validating_institution
1142
+
1143
+ # Initialises a new Module instance
1144
+ # @param (see LUSI::API::Course::ModuleBase#initialize)
1145
+ # @param assessment_proportions [Array<LUSI::API::Course::AssessmentProportion>, nil] the default assessment
1146
+ # proportions
1147
+ # @param course_convenors [Array<LUSI::API::Person::StaffMember>, nil] the default course convenors
1148
+ # @param lecture_capture_enabled [Boolean, nil] the default lecture-capture-enabled flag
1149
+ # @param module_evaluation_cohorts [Array<LUSI::API::Course::ModuleEvaluationCohort>, nil] the default
1150
+ # module evaluation cohorts
1151
+ # @param partner_module_leaders [Array<LUSI::API::Person::StaffMember>, nil] the default partner module leaders
1152
+ # @param validating_institution [LUSI::API::Organisation::Unit] the default validating institution
1153
+ def initialize(xml = nil, lookup = nil, assessment_proportions: nil, course_convenors: nil,
1154
+ lecture_capture_enabled: nil, module_evaluation_cohorts: nil, partner_module_leaders: nil,
1155
+ validating_institution: nil, **kwargs)
1156
+ super(xml, lookup, **kwargs)
1157
+ @assessment_proportions = LUSI::API::Core::XML.xml(xml,
1158
+ 'xmlns:AssessmentProportions/xmlns:AssessmentProportion',
1159
+ assessment_proportions) { |a| AssessmentProportion.new(a, lookup) }
1160
+ @course_convenors = LUSI::API::Core::XML.xml(xml, 'xmlns:CourseConvenor/xmlns:StaffMember',
1161
+ course_convenors) { |s| LUSI::API::Person::StaffMember.new(s, lookup) }
1162
+ @lecture_caputure_enabled = LUSI::API::Core::XML.xml_boolean_at(xml, 'xmlns:LectureCaptureEnabled',
1163
+ lecture_capture_enabled)
1164
+ @module_evaluation_cohorts = LUSI::API::Core::XML.xml(xml, 'xmlns:ModuleEvaluationCohorts/xmlns:ModuleEvaluationCohort',
1165
+ module_evaluation_cohorts) { |m| ModuleEvaluationCohort.new(m, lookup) }
1166
+ @partner_module_leaders = LUSI::API::Core::XML.xml(xml, 'xmlns:PartnerModuleLeader/xmlns:StaffMember',
1167
+ partner_module_leaders) { |s| LUSI::API::Person::StaffMember.new(s, lookup) }
1168
+ @validating_institution = LUSI::API::Core::XML.lookup(xml, lookup, :institution,
1169
+ 'xmlns:ValidatingInstitution/xmlns:Identity',
1170
+ validating_institution)
1171
+ end
1172
+
1173
+ # @see (LUSI::API::Course::ModuleBase#enrolment_lookup_indices)
1174
+ def enrolment_lookup_indices
1175
+ [:module_staff, :module_student]
1176
+ end
1177
+
1178
+ # Returns a hash of parameters for the LUSI API call
1179
+ # @param (see LUSI::API::Course::ModuleBase#get_instance_params)
1180
+ # @param awarding_institution_id [String, nil] the awarding institution identity code
1181
+ def self.get_instance_params(validating_institution_id: nil, **kwargs)
1182
+ params = super(**kwargs)
1183
+ params[:ValidatingInstitutionId] = kwargs.fetch(:validating_institution_id, '')
1184
+ params
1185
+ end
1186
+
1187
+ # Returns the LUSI API endpoint
1188
+ # @return [String] the LUSI API endpoint
1189
+ def self.lusi_ws_endpoint
1190
+ 'CourseManager.asmx'
1191
+ end
1192
+
1193
+ # Returns the LUSI API method
1194
+ # @return [String] the LUSI API method
1195
+ def self.lusi_ws_method
1196
+ 'GetModuleFullDetails'
1197
+ end
1198
+
1199
+ # Returns the root element name of the LUSI API XML response
1200
+ # @return [String] the root element name of the LUSI API XML response
1201
+ def self.lusi_ws_xml_root
1202
+ 'ModuleRecord'
1203
+ end
1204
+
1205
+ end
1206
+
1207
+
1208
+ # Represents a scheme (or programme) of study in the LUSI API
1209
+ class SchemeOfStudy < ModuleBase
1210
+
1211
+ # @!attribute [rw] awarding_institution
1212
+ # @return [LUSI::API::Organisation::Unit, nil] the awarding institution for the scheme of study
1213
+ attr_accessor :awarding_institution
1214
+
1215
+ # @!attribute [rw] credit_points
1216
+ # @return [LUSI::API::Course::CreditPoints, nil] the required credit points for the scheme of study
1217
+ attr_accessor :credit_points
1218
+
1219
+ # @!attribute [rw] length
1220
+ # @return [LUSI::API::Course::Length, nil] the length of the scheme of study
1221
+ attr_accessor :length
1222
+
1223
+ # @!attribute [rw] mode_of_study
1224
+ # @return [LUSI::API::Core::Code, nil] the scheme's mode of study
1225
+ attr_accessor :mode_of_study
1226
+
1227
+ # @!attribute [rw] qualification
1228
+ # @return [String, nil] the qualification awarded by the scheme of study
1229
+ attr_accessor :qualification
1230
+
1231
+ # @!attribute [rw] ucas_course_code
1232
+ # @return [String, nil] the UCAS course code for the scheme of study
1233
+ attr_accessor :ucas_course_code
1234
+
1235
+ # Initialises a new SchemeOfStudy instance
1236
+ # @param (see LUSI::API::Course::ModuleBase#initialize)
1237
+ # @param awarding_institution [LUSI::API::Organisation::Unit, nil] the default awarding institution
1238
+ # @param credit_points [LUSI::API::Course::CreditPoints, nil] the default credit points
1239
+ # @param director_of_studies [Array<LUSI::API::Person::StaffMember>, nil] the default director-of-studies list
1240
+ # @param length [LUSI::API::Course::Length] the default scheme of study length
1241
+ # @param mode_of_study [LUSI::API::Core::Code] the default mode of study
1242
+ # @param qualification [String, nil] the default qualification
1243
+ # @param ucas_course_code [String, nil] the default UCAS course code
1244
+ # @return [void]
1245
+ def initialize(xml = nil, lookup = nil, awarding_institution: nil, credit_points: nil, director_of_studies: nil,
1246
+ length: nil, mode_of_study: nil, qualification: nil, ucas_course_code: nil, **kwargs)
1247
+ super(xml, lookup, **kwargs)
1248
+ @awarding_institution = LUSI::API::Core::XML.lookup(xml, lookup, :organisation,
1249
+ 'xmlns:AwardingInstitution/xmlns:Identity',
1250
+ awarding_institution)
1251
+ @credit_points = CreditPoints.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:CreditPoints', credit_points), lookup)
1252
+ @director_of_studies = LUSI::API::Core::XML.xml(xml, 'xmlns:DirectorOfStudies/xmlns:StaffMember',
1253
+ director_of_studies) { |s| LUSI::API::Person::StaffMember.new(s, lookup) }
1254
+ @length = Length.new(LUSI::API::Core::XML.xml_at(xml, 'xmlns:Length', length), lookup)
1255
+ @mode_of_study = LUSI::API::Core::Code.new(LUSI::API::Core::XML::xml_at(xml, 'xmlns:ModeOfStudy',
1256
+ mode_of_study), lookup)
1257
+ @qualification = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:Qualification', qualification)
1258
+ @ucas_course_code = LUSI::API::Core::XML.xml_content_at(xml, 'xmlns:UCASCourseCode', ucas_course_code)
1259
+ end
1260
+
1261
+ # @see (LUSI::API::Course::ModuleBase#enrolment_lookup_indices)
1262
+ def enrolment_lookup_indices
1263
+ [:scheme_staff, :scheme_student]
1264
+ end
1265
+
1266
+ protected
1267
+
1268
+ # Returns a hash of parameters for the LUSI API call
1269
+ # @param (see LUSI::API::Course::ModuleBase#get_instance_params)
1270
+ # @param awarding_institution_id [String, nil] the awarding institution identity code
1271
+ def self.get_instance_params(awarding_institution_id: nil, **kwargs)
1272
+ params = super(**kwargs)
1273
+ params[:AwardingInstitutionId] = kwargs.fetch(:awarding_institution_id, '')
1274
+ params
1275
+ end
1276
+
1277
+ # Returns the LUSI API endpoint
1278
+ # @return [String] the LUSI API endpoint
1279
+ def self.lusi_ws_endpoint
1280
+ 'General.asmx'
1281
+ end
1282
+
1283
+ # Returns the LUSI API method
1284
+ # @return [String] the LUSI API method
1285
+ def self.lusi_ws_method
1286
+ 'GetSchemesOfStudy'
1287
+ end
1288
+
1289
+ # Returns the root element name of the LUSI API XML response
1290
+ # @return [String] the root element name of the LUSI API XML response
1291
+ def self.lusi_ws_xml_root
1292
+ 'SchemeOfStudy'
1293
+ end
1294
+
1295
+ end
1296
+
1297
+
1298
+ end
1299
+ end
1300
+ end