skala 0.3.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -4
  3. data/Gemfile +10 -1
  4. data/LICENSE.txt +17 -18
  5. data/README.md +1 -34
  6. data/README.primo_adapter.md +42 -0
  7. data/bin/console +11 -0
  8. data/config/initializers/skala.rb +5 -0
  9. data/config/skala.yml +65 -0
  10. data/db/migrate/20141006133522_create_skala_users.rb +13 -0
  11. data/db/migrate/20141006133649_create_skala_user_watch_lists.rb +14 -0
  12. data/db/migrate/20141006135644_create_skala_user_watch_list_entries.rb +13 -0
  13. data/db/migrate/20141006140435_create_skala_user_notes.rb +16 -0
  14. data/lib/skala.rb +36 -3
  15. data/lib/skala/adapter.rb +122 -4
  16. data/lib/skala/adapter/authenticate_user.rb +4 -0
  17. data/lib/skala/adapter/create_user_hold_request.rb +7 -0
  18. data/lib/skala/adapter/create_user_hold_request/result.rb +10 -0
  19. data/lib/skala/adapter/delete_user_hold_request.rb +7 -0
  20. data/lib/skala/adapter/get_record_holdable_items.rb +5 -0
  21. data/lib/skala/adapter/get_record_holdable_items/result.rb +14 -0
  22. data/lib/skala/adapter/get_record_items.rb +5 -0
  23. data/lib/skala/adapter/get_record_items/result.rb +14 -0
  24. data/lib/skala/adapter/get_records.rb +5 -0
  25. data/lib/skala/adapter/get_records/result.rb +28 -0
  26. data/lib/skala/adapter/get_user.rb +4 -0
  27. data/lib/skala/adapter/get_user_former_loans.rb +5 -0
  28. data/lib/skala/adapter/get_user_former_loans/result.rb +14 -0
  29. data/lib/skala/adapter/get_user_hold_requests.rb +5 -0
  30. data/lib/skala/adapter/get_user_hold_requests/result.rb +14 -0
  31. data/lib/skala/adapter/get_user_inter_library_loans.rb +5 -0
  32. data/lib/skala/adapter/get_user_inter_library_loans/result.rb +14 -0
  33. data/lib/skala/adapter/get_user_loans.rb +5 -0
  34. data/lib/skala/adapter/get_user_loans/result.rb +14 -0
  35. data/lib/skala/adapter/get_user_transactions.rb +5 -0
  36. data/lib/skala/adapter/get_user_transactions/result.rb +14 -0
  37. data/lib/skala/adapter/operation.rb +2 -0
  38. data/lib/skala/adapter/operation/request.rb +6 -0
  39. data/lib/skala/adapter/operation/result.rb +7 -0
  40. data/lib/skala/adapter/renew_user_loan.rb +7 -0
  41. data/lib/skala/adapter/renew_user_loan/result.rb +7 -0
  42. data/lib/skala/adapter/renew_user_loans.rb +5 -0
  43. data/lib/skala/adapter/renew_user_loans/result.rb +9 -0
  44. data/lib/skala/adapter/search.rb +6 -0
  45. data/lib/skala/adapter/search/request.rb +91 -0
  46. data/lib/skala/adapter/search/request/date_histogram_facet.rb +5 -0
  47. data/lib/skala/adapter/search/request/facet.rb +29 -0
  48. data/lib/skala/adapter/search/request/histogram_facet.rb +8 -0
  49. data/lib/skala/adapter/search/request/ids_query.rb +6 -0
  50. data/lib/skala/adapter/search/request/match_query.rb +7 -0
  51. data/lib/skala/adapter/search/request/ordered_terms_query.rb +7 -0
  52. data/lib/skala/adapter/search/request/query.rb +18 -0
  53. data/lib/skala/adapter/search/request/query_string_query.rb +9 -0
  54. data/lib/skala/adapter/search/request/range_facet.rb +10 -0
  55. data/lib/skala/adapter/search/request/range_facet/range.rb +9 -0
  56. data/lib/skala/adapter/search/request/range_query.rb +8 -0
  57. data/lib/skala/adapter/search/request/simple_query_string_query.rb +8 -0
  58. data/lib/skala/adapter/search/request/sort_request.rb +15 -0
  59. data/lib/skala/adapter/search/request/terms_facet.rb +8 -0
  60. data/lib/skala/adapter/search/request/unscored_terms_query.rb +7 -0
  61. data/lib/skala/adapter/search/result.rb +22 -0
  62. data/lib/skala/adapter/search/result/facet.rb +15 -0
  63. data/lib/skala/adapter/search/result/histogram_facet.rb +12 -0
  64. data/lib/skala/adapter/search/result/histogram_facet/entry.rb +8 -0
  65. data/lib/skala/adapter/search/result/hit.rb +13 -0
  66. data/lib/skala/adapter/search/result/terms_facet.rb +14 -0
  67. data/lib/skala/adapter/search/result/terms_facet/term.rb +8 -0
  68. data/lib/skala/adapter/update_user.rb +4 -0
  69. data/lib/skala/aleph_adapter.rb +47 -0
  70. data/lib/skala/aleph_adapter/authenticate_user.rb +27 -0
  71. data/lib/skala/aleph_adapter/create_user_hold_request.rb +63 -0
  72. data/lib/skala/aleph_adapter/delete_user_hold_request.rb +29 -0
  73. data/lib/skala/aleph_adapter/get_record.rb +22 -0
  74. data/lib/skala/aleph_adapter/get_record_holdable_items.rb +29 -0
  75. data/lib/skala/aleph_adapter/get_record_items.rb +111 -0
  76. data/lib/skala/aleph_adapter/get_user.rb +49 -0
  77. data/lib/skala/aleph_adapter/get_user_former_loans.rb +21 -0
  78. data/lib/skala/aleph_adapter/get_user_hold_requests.rb +102 -0
  79. data/lib/skala/aleph_adapter/get_user_inter_library_loans.rb +66 -0
  80. data/lib/skala/aleph_adapter/get_user_loans.rb +93 -0
  81. data/lib/skala/aleph_adapter/get_user_transactions.rb +96 -0
  82. data/lib/skala/aleph_adapter/renew_user_loan.rb +27 -0
  83. data/lib/skala/aleph_adapter/renew_user_loans.rb +39 -0
  84. data/lib/skala/aleph_adapter/resolve_user.rb +19 -0
  85. data/lib/skala/aleph_adapter/update_user.rb +105 -0
  86. data/lib/skala/common_attributes.rb +19 -0
  87. data/lib/skala/elasticsearch_adapter.rb +33 -0
  88. data/lib/skala/elasticsearch_adapter/search.rb +20 -0
  89. data/lib/skala/elasticsearch_adapter/search/request_transformation.rb +20 -0
  90. data/lib/skala/elasticsearch_adapter/search/request_transformation/add_aggregations.rb +50 -0
  91. data/lib/skala/elasticsearch_adapter/search/request_transformation/add_from.rb +10 -0
  92. data/lib/skala/elasticsearch_adapter/search/request_transformation/add_query.rb +107 -0
  93. data/lib/skala/elasticsearch_adapter/search/request_transformation/add_size.rb +12 -0
  94. data/lib/skala/elasticsearch_adapter/search/request_transformation/add_sort.rb +18 -0
  95. data/lib/skala/elasticsearch_adapter/search/request_transformation/add_version.rb +10 -0
  96. data/lib/skala/elasticsearch_adapter/search/result_transformation.rb +21 -0
  97. data/lib/skala/elasticsearch_adapter/search/result_transformation/set_facets.rb +44 -0
  98. data/lib/skala/elasticsearch_adapter/search/result_transformation/set_hits.rb +18 -0
  99. data/lib/skala/elasticsearch_adapter/search/result_transformation/set_total_hits.rb +10 -0
  100. data/lib/skala/engine.rb +14 -0
  101. data/lib/skala/get_user_result.rb +14 -0
  102. data/lib/skala/hold_request.rb +24 -0
  103. data/lib/skala/item.rb +15 -0
  104. data/lib/skala/loan.rb +18 -0
  105. data/lib/skala/primo_adapter.rb +34 -0
  106. data/lib/skala/primo_adapter/get_records.rb +24 -0
  107. data/lib/skala/primo_adapter/search.rb +13 -0
  108. data/lib/skala/primo_adapter/search/request_transformation.rb +40 -0
  109. data/lib/skala/primo_adapter/search/request_transformation/add_queries.rb +97 -0
  110. data/lib/skala/primo_adapter/search/request_transformation/add_sort_by_list.rb +37 -0
  111. data/lib/skala/primo_adapter/search/request_transformation/embed_inner_search_request.rb +13 -0
  112. data/lib/skala/primo_adapter/search/request_transformation/serialize_target_as_xml.rb +11 -0
  113. data/lib/skala/primo_adapter/search/request_transformation/set_bulk_size.rb +12 -0
  114. data/lib/skala/primo_adapter/search/request_transformation/set_institution.rb +12 -0
  115. data/lib/skala/primo_adapter/search/request_transformation/set_languages.rb +15 -0
  116. data/lib/skala/primo_adapter/search/request_transformation/set_locations.rb +19 -0
  117. data/lib/skala/primo_adapter/search/request_transformation/set_on_campus.rb +13 -0
  118. data/lib/skala/primo_adapter/search/request_transformation/set_start_index.rb +12 -0
  119. data/lib/skala/primo_adapter/search/request_transformation/setup_inner_search_request.rb +33 -0
  120. data/lib/skala/primo_adapter/search/request_transformation/setup_target.rb +28 -0
  121. data/lib/skala/primo_adapter/search/request_transformation/toggle_bool_operator.rb +13 -0
  122. data/lib/skala/primo_adapter/search/result_transformation.rb +30 -0
  123. data/lib/skala/primo_adapter/search/result_transformation/add_hits.rb +13 -0
  124. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation.rb +46 -0
  125. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_creator.rb +10 -0
  126. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_description.rb +10 -0
  127. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_edition.rb +10 -0
  128. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_fulltext_available.rb +12 -0
  129. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_id.rb +11 -0
  130. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_identifier.rb +46 -0
  131. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_is_part_of.rb +14 -0
  132. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_language.rb +10 -0
  133. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_metadata.rb +13 -0
  134. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_openurl.rb +23 -0
  135. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_publisher.rb +10 -0
  136. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_source.rb +10 -0
  137. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_subject.rb +10 -0
  138. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_title.rb +10 -0
  139. data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_year_of_publication.rb +10 -0
  140. data/lib/skala/primo_adapter/search/result_transformation/fix_primo_facets_bugs.rb +108 -0
  141. data/lib/skala/primo_adapter/search/result_transformation/parse_search_brief_response.rb +20 -0
  142. data/lib/skala/primo_adapter/search/result_transformation/set_facets.rb +71 -0
  143. data/lib/skala/primo_adapter/search/result_transformation/set_total_hits.rb +13 -0
  144. data/lib/skala/primo_adapter/search/result_transformation/sort_terms_facets_terms.rb +14 -0
  145. data/lib/skala/primo_adapter/soap_api.rb +15 -0
  146. data/lib/skala/primo_adapter/soap_api/search_brief.rb +25 -0
  147. data/lib/skala/record.rb +85 -0
  148. data/lib/skala/record/identifier.rb +9 -0
  149. data/lib/skala/record/is_part_of.rb +11 -0
  150. data/lib/skala/record/link.rb +9 -0
  151. data/lib/skala/record/relation.rb +9 -0
  152. data/lib/skala/transaction.rb +13 -0
  153. data/lib/skala/version.rb +1 -1
  154. data/skala.gemspec +21 -12
  155. data/spec/skala/search_request/ordered_terms_query_spec.rb +6 -0
  156. data/spec/spec_helper.rb +7 -28
  157. metadata +237 -85
  158. data/lib/skala/i18n.rb +0 -46
  159. data/lib/skala/transformation.rb +0 -54
  160. data/lib/skala/transformation/step.rb +0 -24
  161. data/spec/assets/locales/de.yml +0 -14
  162. data/spec/assets/locales/en.yml +0 -9
  163. data/spec/assets/transformation/some_class.rb +0 -2
  164. data/spec/skala/adapter/operation_spec.rb +0 -19
  165. data/spec/skala/adapter_spec.rb +0 -2
  166. data/spec/skala/i18n_spec.rb +0 -95
  167. data/spec/skala/transformation/step_spec.rb +0 -36
  168. data/spec/skala/transformation_spec.rb +0 -89
  169. data/spec/skala_spec.rb +0 -2
@@ -0,0 +1,111 @@
1
+ require "nokogiri"
2
+ require "skala/adapter/get_record_items"
3
+ require_relative "../aleph_adapter"
4
+ require_relative "./resolve_user"
5
+
6
+ class Skala::AlephAdapter::GetRecordItems < Skala::Adapter::GetRecordItems
7
+ include parent::ResolveUser
8
+
9
+ def call(document_number, options = {})
10
+ document_base = options[:document_base] || @adapter.default_document_base
11
+ record_id = "#{document_base}#{document_number}"
12
+ resolved_user_id = resolve_user(options[:username]) if options[:username]
13
+
14
+ aleph_options = { patron: resolved_user_id, view: :full }.compact
15
+ raw_aleph_response = adapter.restful_api.record(record_id).items.get(aleph_options)
16
+
17
+ if raw_aleph_response.include?("<error>")
18
+ return nil
19
+ else
20
+ self.class::Result.new(
21
+ items: Nokogiri::XML(raw_aleph_response).xpath("//item").map do |_item|
22
+ {
23
+ id: id(_item),
24
+ availability: availability(_item),
25
+ due_date: due_date(_item),
26
+ expected_date: expected_date(_item),
27
+ hold_request_can_be_created: hold_request_can_be_created(_item),
28
+ item_status: item_status(_item),
29
+ number_of_hold_requests: number_of_hold_requests(_item),
30
+ note: note(_item),
31
+ record: {
32
+ id: document_number
33
+ },
34
+ status: status(_item)
35
+ }
36
+ end,
37
+ source: raw_aleph_response
38
+ )
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def availability(item)
45
+ case status(item)
46
+ when :on_shelf, :reshelving then :available
47
+ else :not_available
48
+ end
49
+ end
50
+
51
+ def due_date(item)
52
+ if status(item) == :loaned
53
+ Date.strptime(item.at_xpath("./status").content[/\d\d\/\d\d\/\d\d/], "%d/%m/%y")
54
+ end
55
+ end
56
+
57
+ def hold_request_can_be_created(item)
58
+ if allowed = item.at_xpath("./info[@type='HoldRequest']/@allowed").try(:content).presence
59
+ allowed == "Y"
60
+ end
61
+ end
62
+
63
+ def id(item)
64
+ item.attr("href")[/[^\/]+\Z/][/\A[^?]+/]
65
+ end
66
+
67
+ def expected_date(item)
68
+ if status(item) == :expected
69
+ Date.strptime(item.at_xpath("./status").content[/\d\d\/\d\d\/\d\d/], "%d/%m/%y")
70
+ end
71
+ end
72
+
73
+ def item_status(item)
74
+ item.at_xpath("./z30/z30-item-status").try(:content)
75
+ end
76
+
77
+ def number_of_hold_requests(item)
78
+ if queue = item.at_xpath("./queue").try(:content).presence
79
+ queue[/\A\d+/].try(:to_i) # example: "1 request(s) of 11 items."
80
+ end || 0
81
+ end
82
+
83
+ def note(item)
84
+ [
85
+ item.at_xpath("./z30/z30-description").try(:content),
86
+ item.at_xpath("./z30/z30-note-opac").try(:content)
87
+ ]
88
+ .map(&:presence)
89
+ .compact
90
+ .try do |_array|
91
+ _array.length <= 1 ? _array.first : _array
92
+ end
93
+ end
94
+
95
+ def status(item)
96
+ aleph_status = item.at_xpath("./status").try(:content).try(:gsub, /requested/i, "") # remove requested states
97
+
98
+ case aleph_status
99
+ when "" then :on_shelf # Exemplar steht im Regal
100
+ when /on shelf/i then :on_shelf # Exemplar steht im Regal
101
+ when /^\d\d\/\d\d\/\d\d/ then :loaned # Exemplar ist entliehen
102
+ when /Effective due date: \d\d\/\d\d\/\d\d/ then :loaned # Exemplar ist entliehen (Rückruf)
103
+ when /reshelving/i then :reshelving # Exemplar wird zurückgestellt
104
+ when /on hold/i then :on_hold # Exemplar ist bereitgestellt
105
+ when /expected/i then :expected # Exemplar wird erwartet (es kann dann noch ein Datum geben)
106
+ when /claimed returned/i then :claimed_returned # Exemplar ist angeblich zurück
107
+ when /lost/i then :lost # Exemplar ist verloren gegangen
108
+ else :unknown
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,49 @@
1
+ require "skala/adapter/get_user"
2
+ require "skala/get_user_result"
3
+ require_relative "../aleph_adapter"
4
+
5
+ class Skala::AlephAdapter::GetUser < Skala::Adapter::GetUser
6
+ def call(username, options = {})
7
+ user_library = options[:user_library] || @adapter.default_user_library
8
+ username = username.upcase # ensure that username/id is always upcased for request/result
9
+
10
+ raw_aleph_result = @adapter.x_services.post(
11
+ op: :"bor-info",
12
+ bor_id: username,
13
+ library: user_library,
14
+ cash: "B",
15
+ hold: "P",
16
+ loans: "P"
17
+ )
18
+
19
+ if raw_aleph_result.include?("<error>")
20
+ return nil
21
+ else
22
+ fields = Hash.from_xml(raw_aleph_result)
23
+
24
+ Skala::GetUserResult.new(
25
+ cash_balance: cash_balance(fields),
26
+ email_address: fields["bor_info"]["z304"]["z304_email_address"],
27
+ expiry_date: Date.strptime(fields["bor_info"]["z305"]["z305_expiry_date"], "%d/%m/%Y"),
28
+ id: username,
29
+ first_name: fields["bor_info"]["z303"]["z303_name"].split(",").last.strip,
30
+ last_name: fields["bor_info"]["z303"]["z303_name"].split(",").first.strip,
31
+ number_of_hold_requests: [fields["bor_info"]["item_h"]].flatten(1).compact.length,
32
+ number_of_loans: [fields["bor_info"]["item_l"]].flatten(1).compact.length,
33
+
34
+ fields: fields
35
+ )
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def cash_balance(fields)
42
+ balance = fields["bor_info"]["balance"].to_f
43
+ sign = fields["bor_info"]["sign"]
44
+ loans = [fields["bor_info"]["item_l"]].flatten(1).compact
45
+ current_fines = loans.map { |_loan| _loan["current_fine"].to_f }
46
+
47
+ balance * (sign == "D" ? -1 : 1) - current_fines.inject(0.0) { |sum, fine| sum + (fine || 0.0) }
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ require "nokogiri"
2
+ require "skala/adapter/get_user_former_loans"
3
+ require_relative "../aleph_adapter"
4
+ require_relative "./get_user_loans"
5
+
6
+ class Skala::AlephAdapter::GetUserFormerLoans < Skala::Adapter::GetUserFormerLoans
7
+ def call(username, options = {})
8
+ get_user_loans_result = get_user_loans(username, type: :history)
9
+
10
+ self.class::Result.new(
11
+ former_loans: get_user_loans_result.loans,
12
+ source: get_user_loans_result.source
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def get_user_loans(*args)
19
+ adapter.class::GetUserLoans.new(adapter).call(*args)
20
+ end
21
+ end
@@ -0,0 +1,102 @@
1
+ require "nokogiri"
2
+ require "skala/adapter/get_user_hold_requests"
3
+ require_relative "./resolve_user"
4
+ require_relative "../aleph_adapter"
5
+
6
+ class Skala::AlephAdapter::GetUserHoldRequests < Skala::Adapter::GetUserHoldRequests
7
+ include parent::ResolveUser
8
+
9
+ def call(username, options = {})
10
+ resolved_user_id = resolve_user(username.upcase)
11
+
12
+ raw_aleph_response = adapter.restful_api.patron(resolved_user_id).circulationActions.requests.holds.get(view: :full)
13
+
14
+ if raw_aleph_response.include?("<error>")
15
+ return nil
16
+ else
17
+ self.class::Result.new(
18
+ hold_requests: Nokogiri::XML(raw_aleph_response).xpath("//hold-request").map do |_hold_request|
19
+ {
20
+ id: id(_hold_request),
21
+ deleteable: deleteable?(_hold_request),
22
+ place_in_queue: place_in_queue(_hold_request),
23
+ creation_date: creation_date(_hold_request),
24
+ begin_request_date: begin_request_date(_hold_request),
25
+ end_request_date: end_request_date(_hold_request),
26
+ begin_hold_date: begin_hold_date(_hold_request),
27
+ end_hold_date: end_hold_date(_hold_request),
28
+ record: {
29
+ id: record_id(_hold_request)
30
+ },
31
+ status: status(_hold_request)
32
+ }
33
+ end,
34
+ source: raw_aleph_response
35
+ )
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def id(hold_request)
42
+ hold_request.attr("href")[/[^\/]+\Z/][/\A[^?]+/]
43
+ end
44
+
45
+ def creation_date(hold_request)
46
+ if date = hold_request.at_xpath("./z37/z37-open-date").try(:content)
47
+ Date.strptime(date, "%Y%m%d")
48
+ end
49
+ end
50
+
51
+ def deleteable?(hold_request)
52
+ hold_request.attr("delete") == "Y" && !hold_request.at_xpath(".//status").content.presence.try(:include?, "On hold until")
53
+ end
54
+
55
+ def place_in_queue(hold_request)
56
+ hold_request.at_xpath(".//status").try(:content).presence.try(:[], /Waiting in position \d+/).try(:[], /\d+/).try(:to_i)
57
+ end
58
+
59
+ def record_id(hold_request)
60
+ hold_request.at_xpath(".//z13-doc-number").try(:content)
61
+ end
62
+
63
+ def begin_request_date(hold_request)
64
+ if date = hold_request.at_xpath(".//z37-request-date").try(:content).presence
65
+ Date.strptime(date, "%Y%m%d")
66
+ end
67
+ rescue
68
+ nil
69
+ end
70
+
71
+ def end_request_date(hold_request)
72
+ if date = hold_request.at_xpath(".//z37-end-request-date").try(:content).presence
73
+ Date.strptime(date, "%Y%m%d")
74
+ end
75
+ rescue
76
+ nil
77
+ end
78
+
79
+ def begin_hold_date(hold_request)
80
+ if date = hold_request.at_xpath(".//z37-hold-date").try(:content).presence
81
+ Date.strptime(date, "%Y%m%d")
82
+ end
83
+ rescue
84
+ nil
85
+ end
86
+
87
+ def end_hold_date(hold_request)
88
+ if date = hold_request.at_xpath(".//z37-end-hold-date").try(:content).presence
89
+ Date.strptime(date, "%Y%m%d")
90
+ end
91
+ rescue
92
+ nil
93
+ end
94
+
95
+ def status(hold_request)
96
+ case hold_request.at_xpath(".//z37-status").try(:content).presence.try(:upcase)
97
+ when "WAITING IN QUEUE" then :requested
98
+ when "S" then :on_hold
99
+ when "IN PROCESS" then :in_process
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,66 @@
1
+ require "nokogiri"
2
+ require "skala/adapter/get_user_inter_library_loans"
3
+ require_relative "./resolve_user"
4
+ require_relative "../aleph_adapter"
5
+
6
+ class Skala::AlephAdapter::GetUserInterLibraryLoans < Skala::Adapter::GetUserInterLibraryLoans
7
+ include parent::ResolveUser
8
+
9
+ def call(username, options = {})
10
+ resolved_user_id = resolve_user(username)
11
+ raw_aleph_response = adapter.restful_api.patron(resolved_user_id).circulationActions.requests.ill.get(view: :brief)
12
+
13
+ if raw_aleph_response.include?("<error>")
14
+ return nil
15
+ else
16
+ self.class::Result.new(
17
+ inter_library_loans: Nokogiri::XML(raw_aleph_response).xpath("//ill-request").map do |_ill_request|
18
+ {
19
+ id: id(_ill_request),
20
+ due_date: due_date(_ill_request),
21
+ record: {
22
+ creator: creator(_ill_request),
23
+ id: record_id(_ill_request),
24
+ title: title(_ill_request),
25
+ year_of_publication: year_of_publication(_ill_request)
26
+ },
27
+ renewable: renewable(_ill_request)
28
+ }
29
+ end,
30
+ source: raw_aleph_response
31
+ )
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def creator(element)
38
+ element.at_xpath(".//z13-author").try(:content).presence.try(:split, ";").try(:map, &:strip)
39
+ end
40
+
41
+ def id(element)
42
+ element.attr("href")[/[^\/]+\Z/][/\A[^?]+/]
43
+ end
44
+
45
+ def due_date(element)
46
+ if _due_date = element.at_xpath(".//z36-due-date|.//z36h-due-date").try(:content)
47
+ Date.strptime(_due_date, "%Y%m%d")
48
+ end
49
+ end
50
+
51
+ def record_id(element)
52
+ element.at_xpath(".//z410-doc-number").try(:content).presence
53
+ end
54
+
55
+ def renewable(element)
56
+ element.attr("renew") == "Y"
57
+ end
58
+
59
+ def title(element)
60
+ element.at_xpath(".//z13-title").try(:content).presence
61
+ end
62
+
63
+ def year_of_publication(element)
64
+ element.at_xpath(".//z13-year").try(:content).presence
65
+ end
66
+ end
@@ -0,0 +1,93 @@
1
+ require "nokogiri"
2
+ require "skala/adapter/get_user_loans"
3
+ require_relative "./resolve_user"
4
+ require_relative "../aleph_adapter"
5
+
6
+ class Skala::AlephAdapter::GetUserLoans < Skala::Adapter::GetUserLoans
7
+ include parent::ResolveUser
8
+
9
+ def call(username, options = {})
10
+ resolved_user_id = resolve_user(username)
11
+ loans_type = options[:type] == :history ? :history : nil
12
+ aleph_options = { type: loans_type, view: :full }.compact
13
+ raw_aleph_response = adapter.restful_api.patron(resolved_user_id).circulationActions.loans.get(aleph_options)
14
+
15
+ if raw_aleph_response.include?("<error>")
16
+ return nil
17
+ else
18
+ self.class::Result.new(
19
+ loans: Nokogiri::XML(raw_aleph_response).xpath("//loan").map do |_loan|
20
+ {
21
+ id: id(_loan),
22
+ due_date: due_date(_loan),
23
+ fine: fine(_loan),
24
+ loan_date: loan_date(_loan),
25
+ record: {
26
+ id: ils_record_id(_loan),
27
+ title: title(_loan)
28
+ },
29
+ renewable: renewable(_loan),
30
+ returned_date: returned_date(_loan),
31
+ signature: signature(_loan)
32
+ }
33
+ end,
34
+ source: raw_aleph_response
35
+ )
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def id(loan)
42
+ loan.attr("href")[/[^\/]+\Z/][/\A[^?]+/]
43
+ end
44
+
45
+ def due_date(loan)
46
+ if _due_date = loan.at_xpath(".//z36-due-date|.//z36h-due-date").try(:content)
47
+ Date.strptime(_due_date, "%Y%m%d")
48
+ end
49
+ end
50
+
51
+ def loan_date(loan) # only available in full view
52
+ if _loan_date = loan.at_xpath(".//z36-loan-date|.//z36h-loan-date").try(:content)
53
+ Date.strptime(_loan_date, "%Y%m%d")
54
+ end
55
+ end
56
+
57
+ def fine(loan)
58
+ loan.at_xpath(".//fine").try(:content).presence.try(:to_f)
59
+ end
60
+
61
+ def ils_record_id(element)
62
+ element.at_xpath("./z13/z13-doc-number").try(:content).presence
63
+ end
64
+
65
+ def renewable(loan)
66
+ z36_last_renew_date = loan.at_xpath("./z36/z36-last-renew-date").try(:content).presence
67
+
68
+ # maybe its present but "00000000" or something else non valid
69
+ last_renew_date = begin
70
+ z36_last_renew_date.try do |_date|
71
+ Date.strptime(_date, "%Y%m%d")
72
+ end
73
+ rescue ArgumentError
74
+ nil
75
+ end
76
+
77
+ loan.attr("renew") == "Y" && (!last_renew_date || last_renew_date < Date.today)
78
+ end
79
+
80
+ def returned_date(loan)
81
+ if _returned_date = loan.at_xpath(".//z36h-returned-date").try(:content)
82
+ Date.strptime(_returned_date, "%Y%m%d")
83
+ end
84
+ end
85
+
86
+ def title(element)
87
+ element.at_xpath("./z13/z13-title").try(:content).presence
88
+ end
89
+
90
+ def signature(element)
91
+ element.at_xpath("./z13/z13-call-no").try(:content).presence
92
+ end
93
+ end