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,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